内存申请过程
- JVM会试图为相关Java对象在Eden中初始化一块内存区域;
- 当Eden空间足够时,内存申请结束。否则到下一步;
- JVM试图释放在Eden中所有不活跃的对象(minor collection),释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区;
- Survivor区被用来作为Eden及old的中间交换区域,当old区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区;
- 当old区空间不够时,JVM会在old区进行major collection;
- 完全垃圾收集后,若Survivor及old区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现"Out of memory错误";
对象衰老过程
新创建的对象的内存都分配自eden。Minor collection的过程就是将eden和在用survivor space中的活对象copy到空闲survivor space中。对象在young generation里经历了一定次数(可以通过参数配置)的minor collection后,就会被移到old generation中,称为tenuring。GC触发条件
GC类型 | 触发条件 | 触发时发生了什么 | 注意 | 查看方式 |
Minor GC | eden空间不足 | (1)清空Eden+from survivor中所有no ref(无引用)的对象占用的内存 ▲重新调整Eden 和from的大小(parallel GC会触发此项) | 全过程暂停应用 是否为多线程处理由具体的GC决定 | jstat –gcutil gc log |
Full GC | (1)old空间不足 (2)perm空间不足 (3)显示调用System.GC, RMI等的定时触发 (4)YGC时的悲观策略 (5)dump live的内存信息时(jmap –dump:live) | (1)清空heap中no ref的对象 (2)permgen(永久代)中已经被卸载的classloader中加载的class信息 (3)如配置了CollectGenOFirst,则先触发YGC(针对serial GC) (4)如配置了ScavengeBeforeFullGC,则先触发YGC(针对serial GC) | 全过程暂停应用 是否为多线程处理由具体的GC决定 是否压缩需要看配置的具体GC | jstat –gcutil gc log |
GC信息的格式
[GC [<collector>: <starting occupancy1> -> <ending occupancy1>, <pause time1> secs] <starting occupancy3> -> <ending occupancy3>, <pause time3> secs]
<collector> GC为minor收集过程中使用的垃圾收集器起的内部名称.
<starting occupancy1> young generation 在进行垃圾收集前被对象使用的存储空间.
<ending occupancy1> young generation 在进行垃圾收集后被对象使用的存储空间
<pause time1> minor收集使应用暂停的时间长短(秒)
<starting occupancy3> 整个堆(Heap Size)在进行垃圾收集前被对象使用的存储空间
<ending occupancy3> 整个堆(Heap Size)在进行垃圾收集后被对象使用的存储空间
<pause time3> 整个垃圾收集使应用暂停的时间长短(秒),包括major收集使应用暂停的时间(如果发生了major收集).