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

  • 时间:
  • 浏览:7
  • 来源:大发uu快3_uu快3腾讯app_大发uu快3腾讯app

这里我们都都儿先说句题外话,相信我们都都儿在面试中老要 被问到介绍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)。从内存回收的高度来看,可能现在收集器基本都采用分代收集算法,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.运行时数据区脑图