您的位置:首页 > 其它

漫谈jvm垃圾收集(3)

2017-10-10 08:47 495 查看
在这篇博客漫谈jvm垃圾收集(2)中我们说了目前商业虚拟机进行垃圾收集的通用算法和收集器。这里我们继续深入讨论一些关于垃圾收集的一些细节。

我们前面说了现在大多数虚拟机都是采用分代收集策略,jvm依据不同对象的生存周期不同,将堆分为新生代和老年代,其中新生代又分为Eden 、 S0 、 S1区,其中S0、S1称为Surivivor区,一般Eden和Surivivor比例为8:1,可以使用-XX:SurvivorRatio=8进行比例的设置。其中发生在新生代的GC动作成为Minor
GC,发生在老年代的GC动作成为Major GC/Full GC,由于新生代存在大量朝生夕死的对象所以Minor GC比Major GC更频繁,由于老年代比新生代空间要大并且采用标记-清除算法,这就导致了Major GC比Minor GC要慢很多。

新生代顾名思义就是对象出生的地方,这里发生GC的主要动作流程是:

(1)虚拟机首先检查新分配对象大小是否大于-XX:PreTenureSizeThreShold(单位是B)设置值,大于设置值的对象直接在老年代分配,

如果不大于则检查新分配的对象是否可以在新生代中找到连续的地址空间进行分配,如果可以则直接分配;如果不能找到则触发Minor GC清理空进。

(2)由于老年代为新生代提供了内存分配担保,开始触发Minor GC之前,老年代会先检查自己可使用的连续地址空间十分大于新生代所有对象总空间,如果大于则触发Minor GC;如果不大于,虚拟机检查HandlePromotionFailure设置值是否允许担保失败,如果不允许担保失败则触发Full GC,如果运行担保失败,则虚拟机会继续检查老年代最大可用的连续空间,是否大于历次晋升到老年代对象的平均大小,如果大于则触发Minor
GC。

(3)新生代采用复制算法,标记完成之后将Eden和from区中存活对象复制到to区,之后from区变为to区,to区变为from区,from区中,存活的对象年龄+1,最后清理Eden和From区

(4)在将from区中的对象往to区复制之前,虚拟机会检查from区中是否有对象年龄大于-XX:MaxTenuringThreShold设置的年龄阈值,如果大于则将该对象直接复制到老年代;from空间中相同年龄所有对象的大小总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就也可以直接进入到老年代。



总结一下:

(1)新生代对象什么情况下会进入到老年代

Survivor无法容纳的对象直接进入到老年代

-XX:PreTenureSizeThreShold(单位是B)大于设置值的对象直接在老年代分配

大于-XX:MaxTenuringThreShold设置年龄阈值的对象晋升到老年代
Survivor空间中相同年龄所有对象的大小总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入到老年代

(2)什么情况下会触发新生代GC  (Minor GC)

Eden区域空间被占满了
新创建对象所需空间大小大于Eden所能获得的连续地址空间
CMS设置了CMSScavengeBeforeRemark参数,这样在CMS的Remark之前会先做一次Minor GC来清理新生代,加速之后的Remark的速度。这样整体的stop-the world时间反而断

Full GC时会触发一次Minor GC

(3)什么情况下会触发老年代GC  (Major/Full GC)

新生代直接晋升到老年代的大对象超过了老年代的剩余空间

CMS失败,发生concurrent mode failure会引起Full GC,这是由于CMS并发清除时和用户线程同时运行,用户线程产生的对象大小大于老年代剩余的连续地址空间,这是就会发生concurrent
mode failure,虚拟机就会启动Seril Old收集器开启Full GC

Minor GC后存活的对象超过了老年代剩余空间

Minor GC后每次晋升到老年代的对象的平均大小大于老年代剩余空间,以上两种情况属于老年代为新生代内存分配担保失败

Perm永久代空间不足会触发Full
GC,可以让CMS清理永久代的空间,设置CMSClassUnloadingEnabled
System.gc()引起的Full GC,可以设置DisableExplicitGC来禁止调用System.gc引发Full GC
(4)什么情况下会抛出oom(out of memory)异常

我在这篇博客(1)JVM运行时数据分区中,列举了几个在各个jvm内存区域中抛出oom的情况。实际上jvm中有连个可以配置的参数,与oom的情况有关

-XX:GCTimeLimit=time-limit :
bd75
花费在GC上的时间上限,默认是98,当超过上限时,会抛出OutOfMemory(HeapSpace)的异常
-XX:GCHeapFreeLimit=space-limit :Heap空闲空间的最低比例下限,默认是2,当超过下限时,会抛出OutOfMemory(HeapSpace)的异常
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息