自己动手写写:GC何时触发?

本文是基于Oracle的Hotspot JVM 1.6版本的分析。

 

先来看一下 HotSpot的内存结构:

 

 

备注:在HotSpot中本地方法栈和JVM方法栈是同一个,因此也可以用-Xss控制。


经IBM研究,通常运行的程序有80%--98%的对象是临时对象,因此Hotspot对JVM堆采用了分代的方式来管理,以提升GC的效率。

 

下面我们来看一张堆内存逻辑划分图:


 

分为New Generation或Young Generation(包含Eden Space、S0、S1)、Old GenerationPermanent Generation

 

备注:New Generation中大部分为临时对象,因此采用了复制算法进行实现。通常将对New Generation进行的回收称为Minor GC;对Old Generation进行的回收称为Major GC, 但由于Major GC除并发GC外均需对整个堆以及Permanent Generation进行扫描和回收,因此又称为Full GC。

其中Permanent Generation主要存储了class的信息,详细可参考:

        http://blogs.oracle.com/jonthecollector/entry/presenting_the_permanent_generation

不过在jdk7中此区域要被移除了。

 

下面紧接着的一个问题就是何时进行Minor GC、何时进行Major GC?

结合上图我们来简单的描述下回收的过程:

 

  1. 对象在Eden Space完成内存分配
  2. 当Eden Space满了,再创建对象,会因为申请不到空间,触发Minor GC,进行New(Eden + S0 或 Eden S1) Generation进行垃圾回收
  3. Minor GC时,Eden Space不能被回收的对象被放入到空的Survivor(S0或S1,Eden肯定会被清空),另一个Survivor里不能被GC回收的对象也会被放入这个Survivor,始终保证一个Survivor是空的
  4. 在Step3时,如果发现Survivor区满了,则这些对象被copy到old区,或者Survivor并没有满,但是有些对象已经足够Old,也被放入Old Space。
  5. 当Old Space被放满之后,进行Full GC

 

 

但这个具体还要看JVM是采用的哪种GC方案!

 

New Generation的GC有以下三种:


 

对于上述三种GC方案均是在Eden Space分配不下时,触发GC.

 

Old Generation的GC有以下四种:


 

对于Serial MSC, Parallel MSC, Parallel Compacting而言触发机制为

 

  • Old Generation空间不足
  • Permanent Generation空间不足
  • Minor GC时的悲观策略
  • Minor GC后在Eden上分配内存仍然失败
  • 执行Heap Dump时
  • 外部调用System.gc,可通过-XX:+DisableExplicitGC来禁止
对于CMS而言触发机制为:
  • 当Old Generation空间使用到一定比率时触发;HopSpot V1.6中默认是92%,可通过PrintCMSInitiationStatistics(此参数在V1.5中不能用)来查看这个值到底是多少;可通过CMSInitiatingOccupancyFaction来强制指定,默认值并不是复制在这个值上,是根据如下公式计算出来的:((100 -MinHeapFreeRatio) +(double)(CMSTriggerRatio* MinHeapFreeRatio) / 100.0)/ 100.0;MinHeapFreeRatio默认值:40 CMSTriggerRatio默认值:80
  • 当Permanent Generation采用CMS收集且空间使用到一定比率触发;Permanent Generation采用CMS收集需设置:-XX:+CMSClassUnloadingEnabled Hotspot V1.6中默认为92%;可通过CMSInitiatingPermOccupancyFraction来强制指定,同样,它是根据如下公式计算出来的:((100 -MinHeapFreeRatio) +(double)(CMSTriggerPermRatio* MinHeapFreeRatio) / 100.0)/ 100.0;MinHeapFreeRatio默认值:40 CMSTriggerPermRatio默认值:80
  • Hotspot根据成本计算决定是否需要执行CMS  GC;可通过-XX:+UseCmsInitiatingOccupancyOnly来去掉这个动态执行的策略。
  • 外部调用System.gc,且设置了ExplicitGCIInvokesConcurrent;需要注意,在hotspot 6中,在这种情况下如果应用同时使用了NIO,可能会出现bug。

 

备注:关于究竟采用何种GC方案,在后续JVM调优的章节中再详细阐述。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值