JVM学习笔记二 :垃圾收集的过程分析Eden->Survivor->Tenured



内存申请过程

  1. JVM会试图为相关Java对象在Eden中初始化一块内存区域;
  2. 当Eden空间足够时,内存申请结束。否则到下一步;
  3. JVM试图释放在Eden中所有不活跃的对象(minor collection),释放后若Eden空间仍然不足以放入新对象,则试图将部分Eden中活跃对象放入Survivor区;
  4. Survivor区被用来作为Eden及old的中间交换区域,当old区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区;
  5. 当old区空间不够时,JVM会在old区进行major collection;
  6. 完全垃圾收集后,若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(无引用)的对象占用的内存
(2)将eden+from survivor中所有存活的对象copy到to survivor
(3)一些对象将晋升到old中:
    ▲to sur放不下的
    存活次数超过turning threshold中的
    ▲重新计算tenuring threshold (年龄计数器)
(serial parallel GC会触发此项)

    ▲重新调整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收集).


阅读更多

没有更多推荐了,返回首页