jvm内存结构浅析

Posted by mty on December 5, 2017

jvm内存结构模型

该若干区域有的是jvm启动时候创建,jvm退出销毁,有的则依赖于每个线程;在线程启动时刻创建退出销毁。 ![Markdown]

  1. 程序计数器:程序计数器是一块小的内存区域,该区域是线程私有的内存区域,可以看作每个线程所执行的字节码的行数计数器。记录每个线程的执行位置。jvm的多线程处理是通过现成轮流切换并分配处理器的执行时间来实现的。在任何一个时间片段,一个cpu只能执行一个线程的唯一指令。因此为了线程之间切换到上次执行的位置每个线程需要一个独立的程序计数器来记录上次执行的位置。多个线程之间独立存储,互不影响。是各个线程之间私有的。如果当前线程执行的是java方法则该程序计数器记录的是正在执行的虚拟机的字节码指令的地址,如果执行的是本地(Native)方法则记录为空(Undefined),此区域是唯一一个没有OOM的区域.
  2. 虚拟机栈: 线程私有,他的生命周期和线程相同。每个方法执行的时候都会创建一个栈帧用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法执行的过程中都是对应一个栈帧从入栈到出栈的过程。
    • 局部变量表: 是一组变量值存储空间,用于存储方法内的参数的局部变量值。是通过索引来访问。
    • 操作数栈: 和局部变量区一样,也是一组基于数组的存储空间,但是是通过标准的栈操作压栈和出栈。
    • 动态链接: 虚拟机运行的时候会保存大量的符号引用,可以看作是每个方法的间接引用,然后转换成直接引用。
    • 返回地址: 退出包括正常和异常退出。正常退出会传返回值给上层调用者,异常则不会返回。 当扩展的栈大小不能申请足够的内存时候会抛出OOM异常,StackOverflowError。
  3. 本地方法栈: 和虚拟机站一样,只是他提供给的是本地方法调用的区域。Sun hotpot虚拟机把虚拟机栈和本地方法栈合二为一。该区域抛出的异常和虚拟机一样。StackOverflowError的oom异常。
  4. : 该区域是jvm最大的一块内存区域,是所有线程共享的一块内存区域.在虚拟机启动时候创建,此内存唯一的目的就是存放创建的内存实例.如果堆区域没有足够的内存分配会抛出OOM异常.该区域是GC垃圾回收的主要区域并且按照内存回收区域来分还可以分为年轻代和年老代,按照分代手机算法回收对象实例.
    • 新生代: 程序新创建的对象都是在此区域创建,该区域由eden区域和两块大小的survivor区域组成(通常叫做s1和s2或者from和to区域).
    • 老年代: 用于存放在新生代多次存货的对象.新的对象也可以在次区域分配:大约配置的阈值时候则对象在老年代分配.