聊聊垃圾回收算法( 三 )


 
再来看一下 Full GC 的触发条件,Full GC 的触发条件要复杂一些,主要有这么几种场景:
 
一是,老年代空间不足,老年代代空间不足又分为两种情况:第一是空间真的不足了 。第二是内存碎片,导致没有连续的内存去分配对象,触发 Full GC 。
 
二是,元空间不足 。
 
三是,在某一次新生代回收之后,要晋升到老年代的对象所占用的空间大于了老年代的剩余空间,这个时候也会触发 Full GG 。
 
四是,显式调用了 System.gc() 。System.gc() 的作用是建议垃圾回收容器直径垃圾回收,这个代码是会触发 Full GC 的,你也可以使用这个参数:-XX:DisableExplicitGC 去忽略掉 System.gc() 的调用 。
 
好,介绍到这里可以简单总结一下,分代收集算法是根据对象的生命周期,把内存做的分代 。然后在分配对象的时候,把不同生命周期的对象放在不同代里面,不同的代上选用合适的回收算法进行回收 。
 
比如,新生代里面的对象存活周期一般都比较的短,每次垃圾回收的时候都会发现有大量的对象死去 。那么 IBM 有做过研究,98% 以上的对象都是会很快消亡的,只有少量的对象能够存活,所以新生代可以使用复制算法来完成垃圾收集 。而老年代里面的对象存活率比较高,所以就采用标记-清除算法或者是标记-整理算法进行回收 。
 
那么相比单纯的标记-清除算法、标记-整理算方法以及复制算法三代带来了什么好处呢?
 
首先,分代可以更有效的清除不需要的对象,对于生命周期比较短的对象,对象还处于新生代的时候就会被回收掉了 。
 
其次,分代提升的垃圾回收的效率 。如果不做分代的话,那么需要扫描整个堆里面的对象 。而现在的话只要扫描新生代或者老年代就可以了 。
 
总结 
好,简单总结一下,本课时课我们探讨了五种垃圾口的算法 。基础的垃圾回收算法有标记-清除算法、标记-整理以及复制算法 。另外还探讨了两种综合性的垃圾回收算法,即分代收集算法以及增量算法,同时详细探讨分代收集算法 。
 
最后来总结一下分代收集算法的调优原则:
 
第一,要合理的设置 Survivor 区的大小,因为 Survivor 区对内存的利用率不高 。如果配置的过大的话,内存浪费就会比较严重 。
 
第二,要让 GC 尽量的发生在新生代,也就是让 GC 停留在 Minor GC 的级别 。
尽量减少 Full GC 的发生 。
 
另外,总结有关堆内存的 JVM 参数 。
 
参数作用默认 -XX:NewRatio=n老年代:新生代内存大小比值2-XX:SurvivorRatio=n伊甸园:survivor区内存大小比值8-XX:PretenureSizeThreshold=n对象大小该值就在老年代分配,0表示不做限制0-Xms需小堆内存--Xmx最大堆内存--Xmn新生代大小--XX:+DisableExplicitGC忽略掉 System.gc() 的调用启用-XX:NewSize=n新生代初始内存大小--XX:MaxNewSize=n新生代最大内存-  





推荐阅读