- 堆内存分为:Permanent(持久代)、Head Space(年老代+年轻代)。
持久代主要存放java类定义信息。
Head Space中年老代和年轻代的划分影响垃圾回收。
- 年轻代:
1)所有新生成的对象首先放在年轻代。
年轻代的目标:尽可能快的收集生命周期短的对象。
2)年轻代一般分为三个区:一个Eden,两个Survivor区(from和to)。
大部分对象在Eden区生成。当Eden区满后,会将还存活的对象放到其中一个Survivor区;
当这个Survivor区满后,会将该区中还存活的对象放在另一个Survivor区中。
当另一个Survivor区满后,其中还存活的对象可能会放在年老代中。
3)两个Survivor区是对称的,没有先后关系。
当其中一个Survivor区满后,Eden区和Survivor区中还存活的对象会放到另一个Survivor区。此时s0区为空。所以说Survivor区至少有一个是空的。
4)Survivor区可以配置为多个。
针对年轻代的垃圾回收:Young GC。
-
年老代:
在年轻代中经历了n次垃圾回收依然存活的对象,会被放在年老区。
可以理解为年老代存放生命周期长的对象。
针对年老代的垃圾回收:Full GC。 -
持久代
用于存放静态类型数据,例如Java Class,Method等。持久代对垃圾回收影响不大(年轻代和年老代的划分对垃圾回收影响较大) -
当一组对象生成时,内存申请过程如下:
1)JVM先尝试在年轻代的Eden区为对象申请空间。
2)如果Eden内存空间满足,结束
3)如果Eden空间不足,JVM会尝试释放Eden中所有不活跃对象(Young GC)。释放后Eden空间依然不足的话,JVM会将部分活跃对象移动到Survivor区中。
4)Survivor作为年轻代Eden区和年老代之间的交换区域。如果年老代内存充足,Survivor中存活了一定次数的对象会转移到年老代中。
5)年老代中内存不足时,JVM会在年老代中进行完全的垃圾回收(Full GC)
6)Full GC后,如果Survivor区以及年老代仍然无法存放Eden区中复制过来的对象(Survivor和年老代腾出来的空间还是不能存放Eden中的活跃元素也,就是Eden区仍无法存放新生成的对象),将会出现OUT Of Memory
参考博客: