大发uu快3_uu快3彩票邀请码_大发uu快3彩票邀请码

【JVM从小白学成大佬】2.Java虚拟机运行时数据区

时间:2019-09-11 00:36:09 出处:大发uu快3_uu快3彩票邀请码_大发uu快3彩票邀请码

这里大伙儿 先说句题外话,相信大伙儿 在面试中总爱 被问到介绍Java内存模型,我在面试别人时也会总爱 问你你这个问题。但会 ,往往都有令我比较尴尬,我还话音未落,面试者就会“背诵”一段(Java虚拟机时有堆、土妙招去、虚拟机栈,吧啦吧啦。。。),估计心里还一脸自豪的想幸好哥提前在网上搜过,早有准备。每每你你这个之前 ,我都有忍心打断,可能性“背诵”的真的太顺畅了!

这也怪不得面试者,首先Java虚拟机方面的知识,对中高级守护进程猿来说,工作中正面接触Java虚拟机的东西不多。其次,你你这个其次咱得好好唠唠,网上搜个Java内存模型,度娘推的第一页大都有介绍Java运行时数据区的,起到了一定的误导作用,大写的尴尬。

本篇将给各位小伙伴先完整版介绍Java运行时数据区的组成,Java内存模型也是虚拟机上边的重点,上边会单独抽出一篇来进行介绍。

1.运行时数据区介绍

守护进程运行所需的内存空间,你你这个是只能在编译期就能选则,得要在运行期根据实际运行情况汇报动态地在系统中创建。Java虚拟机在执行Java守护进程的过程中会把它所管理的内存划分为若干个不同的数据区域。那先 区域都有每每个人 的用途,以及创建和销毁的时间,有的区域随着虚拟机守护进程的启动而位于,你你这个区域则依赖用户守护进程的启动和现在现在结束了了而建立和销毁。

如图所示,堆和土妙招区是所有守护进程共享的公共区域,堆和土妙招区所占的内存空间是由JVM负责管理的,在该区域内的内存分配是由HotSpot的内存管理模块维护的,而内存的释放工作则由垃圾埋点器自动完成。虚拟机栈、本地土妙招栈、守护进程计数器是守护进程的私有区域,每个守护进程都关联着唯一的栈和守护进程计数器,并仅能使用属于当事人的那份栈空间和守护进程计算器来执行守护进程。

2.堆(Heap)

对于大多数应用来说,Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块。堆是可供各个守护进程共享的运行时内存区域,在虚拟机启动的之前 就被创建。此内存区域的唯一目的要是存放对象实例,几乎所有的对象实例都有这里分配内存。你你这个点在Java虚拟机规范中的描述要是:所有的对象实例以及数组对象都有在堆上分配。但会 随着JIT编译器的发展与逃逸分析技术逐渐性心智心智心智成熟 图片 的句子的句子是什么是什么图片 图片 图片 图片 图片 的句子是什么,栈上分配、标量替换优化技术可能性是是因为你你这个微妙的变化位于,所有的对象都分配在堆上也渐渐变得都有越来越“绝对”了。

Java堆的容量都才能是固定的,也都才能随着守护进程执行的需求动态扩展,并在不时需不多空间时自动收缩。Java堆都才能位于物理上不连续的内存空间中,假如有一天逻辑上是连续的即可。可能性在堆中越来越内存完成实例分配,但会 堆也无法再扩展时,可能性抛出OutOfMemoryError异常。

Java堆是垃圾埋点器管理的主要区域,但会 你你这个你你这个之前 也被称做“GC堆”(Garbage Collected Heap)。从内存回收的深度1来看,可能性现在埋点器基本都采用分代埋点算法,Java虚拟机将堆划分为新生代和老年代。其中,新生代又被分为Eden区,以及有六个 大小相同的Survivor区(From Survivor,To Survivor)。默认情况汇报下,Java虚拟机采取的是有你这个动态分配的策略(JVM参数-XX:+UsePSAdaptiveSurvivorSizePolicy),根据生成对象的速率,以及Survivor区的使用情况汇报,动态调整Eden区和Survivor区的比例。也都才能通过参数(SurvivorRatio)来调整你你这个比例,SurvivorRatio你你这个参数要是新生代中Eden区与Survivor区的容量比值,默认是8,代表Eden:Survivor=8:1。

是否可能性有六个 对象共用一段内存的事故?

当调用new指令时,会在Eden区划出一块作为存储对象的内存。可能性堆空间是守护进程共享的,但会 直接在这上边划空间是时需进行同步的。但会 ,将有可能性总爱 出先有六个 对象共用一段内存的事故。补救土妙招要是,Java堆中可能性划出多个守护进程私有的分配缓冲区TLAB(Thread Local Allocation Buffer,对应的虚拟机参数-XX:+UseTLAB,默认开启)。

具体来说,每个守护进程都才能向Java虚拟机申请一段连续内存,比如2048字节,作为守护进程私有的TLAB。你你这个操作时需加锁,守护进程时需维护有六个 指针(实际上可能性更多,但重要也都有六个 ),有六个 指向TLAB中空余内存的起始位置,有六个 则指向TLAB末尾。接下来的new指令,便都才能直接通过指针加法(bump the pointer),都许多人叫做指针碰撞来实现,即把指向空余内存位置的指针去掉 所请求的字节数。可能性加法后空余内存指针的值仍小于或等于指向末尾的指针,则代表分配成功。但会 ,TLAB可能性越来越足够的空间来满足本次新建操作。你你这个之前 ,便时需当前守护进程重新申请新的TLAB。

3.土妙招区(Method Area)

土妙招区与堆一样是守护进程共享的,在虚拟机启动的之前 创建,土妙招区可视为堆的有六个 逻辑次责,但会 它却有六个 别叫雷做Non-Heap(非堆),目的应该是与Java堆区分开来。

土妙招区类式于传统语言编译后的代码存储区域,它存储每个类的形状信息,如:

  • 常量池
  • 土妙招数据
  • 土妙招和构造函数的字节码
  • 类、实例、接口初始化时用到的特殊土妙招

备注:《深入理解Java虚拟机》里将土妙招区归纳为用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

Java虚拟机规范对土妙招区的限制非常宽松,除了和Java堆一样不时需连续的内存和都才能选则固定大小可能性可扩展外,还都才能选则不实现垃圾埋点。这区域的内存回收目标主要是针对常量池的回收和对类型的卸载。

4.守护进程计数器(Program Counter Register)

Java虚拟机都才能支持多条守护进程一并执行,每根小Java虚拟机守护进程都有当事人的守护进程计数器。在任意时刻,根小Java虚拟机守护进程只会执行有六个 土妙招的代码,你你这个正在被守护进程执行的土妙招称为该守护进程的当前土妙招(current methon)。可能性你你这个土妙招都有native的,那守护进程计数器保存的要是Java虚拟机正在执行的字节码指令的地址。可能性该土妙招是native土妙招,那守护进程计数器的值为空(undefined)。守护进程计数器的容量大约应当保存有六个 returnAddress类型的数据可能性有六个 与平台相关的本地指针的值。

守护进程计数器是一块较小的内存空间,它都才能看作是当前守护进程所执行的字节码的行号指示器。此内存区域是唯一有六个 在Java虚拟机规范中越来越规定任何OutOfMemoryError情况汇报的区域。

5.虚拟机栈(VM Stack)

每根小Java虚拟机守护进程都有当事人私有的Java虚拟机栈,它的生命周期与守护进程相同。虚拟机栈描述的是Java土妙招执行的内存模型:每个土妙招在执行的一并都有创建有六个 栈帧(stack frame)用于存储局部变量表、操作数栈、动态链接、土妙招出口等信息。每有六个 土妙招从调用直至执行完成的过程,就对应着有六个 栈帧在虚拟机栈中入栈到出栈的过程。

Java虚拟机栈可能性位于如下异常情况汇报:

  • 可能性守护进程请求分配的栈容量超过Java虚拟机栈允许的最大容量,Java虚拟机可能性抛出有六个 StackOverflowError异常。
  • 可能性Java虚拟机栈都才能动态扩展,但会 在尝试扩展的之前 无法申请到足够的内存,可能性在创建新的守护进程时越来越足够的内存区创建对应的虚拟机栈,那Java虚拟机可能性抛出有六个 OutOfMemoryError异常

6.本地土妙招栈(Native Method Stack)

本地土妙招栈与虚拟机栈所发挥的作用是非常类式的,它们之间的区别不过是虚拟机栈为虚拟机执行Java土妙招(也要是字节码)服务,而本地土妙招栈则为虚拟机使用到的native土妙招服务。

Java虚拟机规范允许本地土妙招栈实现成固定大小可能性根据计算来动态扩展和收缩。可能性采用固定大小的本地土妙招栈,越来越每有六个 守护进程的本地土妙招栈容量都才能在创建栈的之前 独立选定。

与虚拟机栈一样,本地土妙招栈区域也会抛出StackOverflowError和OutOfMemoryError异常。

7.扩展知识点

7.1 栈上分配和逃逸分析

在栈中分配的基本思路是有六个的:分析局部变量的作用域仅限于土妙招内部人员,则JVM直接在栈帧内分配对象空间,补救在堆中分配。你你这个分析过程称为逃逸分析(都有叫逸出分析),而栈帧内分配对象的土妙招称为栈上分配

有六个做的目的是减少新生代的埋点次数,间接提高JVM性能。虚拟机是允许堆逃逸分析开关进行配置的,从Sun Java 6u23之前 ,HotSpot默认开启逃逸分析。

7.2 栈帧

栈帧是用于支持虚拟机进行土妙招调用和土妙招执行的数据形状,它是虚拟机运行时数据区中的虚拟机栈的栈元素。栈帧存储了土妙招的局部变量表、操作数栈、动态连接和土妙招返回地址等信息每有六个 土妙招从调用现在现在结束了了至执行完成的过程,都对应着有六个 栈帧在虚拟机栈上边从入栈到出栈的过程。

在编译守护进程代码的之前 ,栈帧中时需多大的局部变量表,多深的操作数栈都可能性完整版选则了,但会 写入到土妙招表的Code属性之中。但会 有六个 栈帧时需分配有几个内存,不多收到守护进程运行期变量数据的影响,而仅仅取决于具体的虚拟机实现。

有六个 守护进程中的土妙招调用链可能性会很长,你你这个你你这个土妙招都一并位于执行情况汇报。对于执行引擎来说,在活动守护进程中,只能位于栈顶的栈帧才是有效的,称为当前栈帧(Current Stack Frame),与你你这个栈帧相关联的土妙招称为当前土妙招(Current Method)。执行引擎运行的所有字节码指令都只针对当前栈帧进行操作。栈帧的概念形状如下:

8.运行时数据区脑图

热门

热门标签