Jvm运行时数据区

作者: RoberLin | 来源:发表于2018-01-31 09:42 被阅读46次

    Java程序在运行的时候,jvm会把所管理的内存根据用途划分成多个区域,这些内存区域根据用途的不同而与不同的管理策略,以及创建和销毁的时间,有的区域是随着虚拟机进程的启动而存在,有些区域则依赖用户线程的启动和结束而创建和销毁。根据《Java虚拟机规范(Java SE 7版)》的规定,jvm所管理的内存包括以下几个运行时数据区域。

    运行时数据区域

    一、程序计数器

    可以理解为当前线程所执行的字节码的行号指示器,各线程有独立的计数器,线程私有。

    线程在执行Java方法时,这个计数器记录的是正在执行的虚拟机字节码指令的地址。此区域是惟一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域

    二、Java虚拟机栈

    线程私有,生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每一个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。

    在Java虚拟机规范中。对这个区域规定了两种异常情况:如果线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果虚拟机栈可以动态扩展,如果占扩时无法申请到足够的内存,就会抛出OutOfMemoryError异常。

    三、本地方法栈

    和虚拟机栈功能一样,只不过服务对象不同,虚拟机栈服务于执行Java方法(字节码),本地方法栈服务于Native方法,。目前有的虚拟机将虚拟机栈和本地方法栈合二为一,例如Sun HotSpot虚拟机。

    四、堆

    Java虚拟机管理的内存中最大的一块。线程共享,在虚拟机启动时创建。用途是存放对象实例和数组,几乎所有的对象实例都存放在这里。也是垃圾回收期管理的主要区域。

    根据采用的回收算法不同,堆也会细分成多个区域,例如,对于采用分代回收算法(现在回收期基本采用的算法),可细分为新生代和老年代,若再细分的话会分为Eden空间,From Survivor空间,To Suvivor空间等,进一步的划分是为了更好的回收内存,或者更快的分配内存。

    Java虚拟机规范中规定,堆内存可以是物理上不连续的内存空间,但是需要逻辑上连续。当前主流的虚拟机都是按照可扩展来实现的(-Xmx最大值和-Xms初始值控制),如果在堆中没有内存完成实例分配,并且堆也无法再扩展,将会抛出OutOfMemoryError异常

    五、方法区

    线程共享,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据,又叫Non-Heap(非堆)。

    对于HotSpot虚拟机而言,又叫永久代,,因为把分代回收扩展到方法区,省去为方法区专门编写内存管理代码的工作。垃圾收集器在这个区域是较少出现的,这个区域的内存回收目标主要是针对常量池的回收和对类型的写在,根据Java虚拟机规范,当方法区没有内存可分配时。将抛出OutOfMemoryError异常。

    方法区还包含叫做运行时常量池的部分,用于存放编译器生成的各种字面量和符号引用。

    相关文章

      网友评论

        本文标题:Jvm运行时数据区

        本文链接:https://www.haomeiwen.com/subject/ueezaxtx.html