程序计数器
记录程序运行的下一条指令的地址,在多线程环境下,每一个线程都有自己的程序计数器
虚拟机栈(JVM Stack)
虚拟机栈是Java方法执行的内存模型,每个方法执行的时候,会在栈中创建一帧用于存储局部变量表、操作数栈、动态链接、方法出口。方法开始调用时,会创建栈帧并入栈,方法执行结束时会出栈。每个线程都有自己的栈。
本地方法栈
与虚拟机栈所发挥的作用是非常相似,本地方法栈则是为虚拟机使用到的Native方法服务,非java方法,线程独有。
堆(Heap)
堆是用于存放对象实例的地方,几乎所有对象实例在堆中分配。堆是线程共享的,这是多线程时同步机制的原因。
堆是GC管理的主要区域,GC在对堆进行回收前,首先要确定对象是否已死(不可能再被使用的对象)。
判断对象是否存活的算法有两种:引用计数算法、可达性分析算法
方法区
方法区也为所以线程所共享,用于存放已加载的类信息、静态变量、常量和即时编译器编译后的代码。-XX:MaxPermSize用于设置方法区大小
年轻代
年轻代内存占1/3
年轻代执行垃圾回收时对性能没有影响,俗称 minor GC
老年代
老年代内存占2/3,
老年代执行垃圾回收时对性能影响比较大,他会停止程序的运行,耗时较长,俗称full GC
垃圾回收过程
新创建的对象首先默认都会被分配到伊甸园。那些超大的对象例外,他们会被直接放到老年代。
当Eden伊甸园区内存满的时候,就会触发执行引擎的Minor GC进行垃圾清理,剩下有用的对象被转移到From区。
当From区内存满的时候,同样会触发执行引擎的Minor GC进行垃圾清理,剩下有用的对象被转移到To区。
如果To区域的对象重新被使用到,就会重新分配给From区。
From到To区 执行GC 循环转换15次之后的对象,就会被转移到老年代。
当老年代执行垃圾回收时如果发现没有无用的对象可以清理时,并且内存已满,这时候新的对象进入就会导致内存溢出(OOM)。