java高*之垃圾回收浅析
如何确定那些对象应该回收?
引用计数器算法
计数器记录对象被引用的次数,如果计数器的值是0,说明没有地方引用此对象,可以被回收。最大的缺点就是不能解决两个对象相互引用的问题。-
枚举根节点算法
根据根节点(比如静态域等)的引用会找到很多引用链,没有在引用链上的对象可以回收。垃圾回收算法
复制算法
把内存一分为二,某个时间只用其中一份内存,当垃圾回收时,把这部分中存活的对象复制到另一区域,清空这一区域内存,等待下次回收。标记清除算法
先把该回收的对象标记出来,垃圾回收的时候直接清除。这会产生大量的内存碎片标记整理算法
先把该回收的对象标记出来,垃圾回收清除后,整理内存,解决了内存碎片的问题,但是是以降低性能为代价的。- 分代收集算法
把内存分代,新生代,年轻代和老年代。
根据研究表明,各代的大小比例:(新生代+年轻代): 老年代 = 1:4,
新生代:年轻代 :年轻代= 8:1:1.
因为新生代和年轻代中的对象百分之九十多的对象都会被回收掉,所以我们某一时刻只用新生代和其中一个年轻代,回收时把存活的对象放到另一个年轻代中,依次类推。
垃圾收集器
Serial
是client模式下的一个很好的选择,曾经是新生代的唯一选择。 通过暂停所有应用的线程来工作,这种暂停应用线程来进行垃圾回收的方式可能不太适应服务器环境。使用参数-XX:+UseSerialGC 来使用此收集器。ParNew
是Serial的多线程版本,是许多server模式下新生代的首选。唯一与CMS合作的。CMS是第一个真正意义上的并发收集器。也是暂停所有的应用线程来进行垃圾回收使用参数-XX:UserParNewGC 来使用此收集器Parallel Scavenge
新生代收集器,复制算法。它是Java虚拟机的默认垃圾收集器,目标达到一个可控制的吞吐量。= 运行用户代码时
间/(用户代码时间+垃圾收集时间);也是暂停所有的应用线程来进行垃圾回收
XX:+UseParallelGC:启用此收集器
XX:MaxGCPauseMillis:垃圾收集停顿时间
XX:GCTimeRidio:直接设置吞吐量
Serial Old
Serial的老年代版本,标记-整理算法。client模式下,Parallel Old
Parallel Scavenge 的老年代版本,标记整理算法,1.6后出现 -XX:+UseParallelOldGCCMS
追求获得最短回收停顿时间为目标的回收器,互联网站或者B/S系统的服务器,标记-清除算法。1.5
只有在如下两种情景才会暂停所有的应用线程:
1.当标记永久代内存空间中的对象时;
2.当进行垃圾回收时,堆内存同步发生了一些变化。
XX:UseConcMarkSweepGCG1
是当今收集器技术发展的最前沿成果之一。1,7后开始使用,面向服务端的垃圾收集器,目标是替换CMS收集器。标记整理算法–
它将堆内存分割成多个独立区域,然后并发地对它们进行垃圾回收
XX:+UseG1GC
一般情况下我们分三组配对使用:Serial和Serial Old 是一对;ParNew和CMS是一对;Parallel Scavenge和Parallel Old是一对。