GC触发条件总结

GC触发条件总结

当Eden内存不够用的时候,某些情况下会尝试到Old里进行分配(比如说要分配的内存很大),如果还是没有分配成功,于是会触发一次ygc的动作,而ygc完成之后我们会再次尝试分配,如果仍不足以分配此时的内存,那会接着做一次full gc(不过此时的soft reference不会被强制回收),将老生代也回收一下,接着再做一次分配,仍然不够分配那会做一次强制将soft reference也回收的full gc,如果还是不能分配,那这个时候就不得不抛出OutOfMemoryError了。这就是Heap里分配内存抛出OutOfMemoryError的具体过程了。

一个老年代并发收集器正在进行的时候,又发生一个年轻代收集器。一但发生这种情况,老年代收集器会被年轻代收集器所中断,知道年轻代收集器结束之后立刻恢复老年代收集器。 ###G1垃圾收集器 G1垃圾垃圾回收器,年轻代的收集方式是并行stop-the-word。G1在垃圾收集线程执行过程中,并行stop-the-word回收,将暂停所有java应用线程,与其他的HotSpot垃圾收集器一样,一但发生年轻代垃圾收集,整个年轻代都会被回收。 G1老年代的垃圾回收方式与其他的HotSpot垃圾回收器有着极大的不同。G1的老年代的收集不会为了释放老年代的空间就会对整个老年代做回收。在任意时刻只有部分老年代会被回收,并且这部分老年代分区将与一次年轻代收集一起被回收。 当超过java堆占用的阈值,G1就会启用一次老年代收集,G1中堆占用的阈值,是根据老年代占用整个堆空间相对比较得出。CMS触发老年代收集所占用的阈值是相对于老年代本身而言。一但达到阈值,一次并发方式的stop-the-world的初始标记阶段会被安排执行。一但初始标记结束就会触发一个并发标记的多线程阶段,标记老年代所有存活的对象,当并发标记结束,并行stop-the-world重新标记就会被启动,标记那些因为在标记阶段同时执行的应用线程导致长生错过的对象。到重新标记结束,G1就拥有老年代分区的完整信息。如果碰到老年代分区里面一个存活的对象都没有,那么在下一阶段-清除阶段,不用做额外的垃圾收集工作就可以被回收利用。在重新标记阶段结束,G1能够识别出最适合回收的老年代集合。 ##G1 G1将java堆分成多个分区。分区的大小依据堆得尺寸而改变,但必须是2的幂,同时最小的1M。最大的32M。可能的分区尺寸为1M,2M,4M,8M,32M。所有的分区都一样,在JVM运行过程中也不会也不会发生改变。分区尺寸是根据堆内存的初始值和最大值的平均数来计算的。对于这个平均堆尺寸,约生成2000个左右分区。例如:16G的堆就会有16/2000=8MB的分区尺寸。 每个分区都有一个已记忆的集合RSet,用来记录分区代指向分区内的引用,这样避免了对整个堆得扫描,使的各个分区的GC更加独立。 一但应用开始创建对象,G1就会选用一个可用分区,并将它指定为Eden分区,让后从总间取出内存块交给java线程。当这个分区满了之后,另一个未被使用的线程再被指定为Eden分区。这个操作会一直持续下去,直到达到Eden分区上线的数量,就触发一次年轻代收集。 一次年轻代收集会回收掉所有年轻代分区,包括Eden分区和survivor分区。这些分区里面的所有存活对象都会被转移到另外一个新的survivor分区或者老年代分区。在当前转移的目标分区满后就会将新的可用分区标记为survivor分区或者老年代分区。 一次GC后老年代的空间占用达到堆空间占用的阈值。G1就会启动一次老年代收集。通过参数-XX:InitiatingHeapOccupancyPercent来控制占用阈值。默认为45%。 当发生巨型对象分配时,G1会找出一个连续的可用集合,第一个分区被标记为巨型分区开始,其他分区被标记为巨型连续分区。如果没有足够的连续可用空间,G1就会触发一次full gc来压缩对空间。巨型分区被认为是老年代的组成成分。G1面临的问题的大量短命的巨型对象分配问题。 ##G1 发生full gc G1发生fullGC会对整个堆内存全面压缩。而且G1的full gc活动是单线程的。可能会导致异常长的暂停时间。G1的设计方式希望是full gc不在是必须。 ##并发周期 一个G1的并发周期包含了几个阶段的活动:初始标记,并发根分区扫描,并发标记,重新标记以及清除。 初始标记阶段目的是收集所有的GC根,根是对象图的起点。为了从应用线程中收集根引用,必须先暂停这些应用,所有初始标记阶段是stop-the-world方式的。无论年轻代GC都必须收集所有的根。 并发标记的最后阶段,找出那些没有任何存活对象的分区,这些分区不会被添加年轻代或混合GC,到将他们添加到可用分区列表里面。G1在用光分区之前完成标记阶段就很重要,如果做不到就退回去发生一次full gc。 ##G1参数 -XX:G1MixedGCCountTarget,在JDK8u45中缺省值为8,它是GC混合数量的目标选项,它的意义是给标记周期结束之后所能启动混合收集的数目设置一个物理限制。G1的垃圾收集器根据混合GC数量目标值,对可被收集的候选老年代分区总数进行平均拆分,结果设置为每次收集回收老年代的最小数量。 每次混合收集老年代CSet最小数量=混合收集周期将回收的候选老年代分区总数/G1MixedGCCountTarget -XX:G1HeapWastePercent缺省值为java堆总大小的5%,这个参数对于控制在一次混合收集周期中回收老年代分区数有很重要的作用。对于每次混合收集暂停,G1垃圾收集器根据那些能被回收的死亡对象计算出可被回收堆空间的大小。一但G1垃圾收集器达到堆废物阈值的百分比,G1垃圾收集器就不会启动新的混合收集器,同时混合周期也将结束。设置堆废物百分比本质上是你愿意浪费一定数量的堆空间,通过他们可以有效的提升混合周期的效率,因此每个混合周期所包含的混合收集数可以通过两个方面来控制。

转载于:https://my.oschina.net/hongliangsun/blog/1613374

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值