经典垃圾收集器:
Serial 收集器(新生代):
Serial 收集器用于新生代,并且在JDK 1.3.1 之前是新生代的唯一选择。Serial 收集器是单线线程的垃圾收集器,这里的单线程不仅指的是它只会使用一个处理器或者一个线程工作,而更重要的是在它工作时,必须暂停其他工作线程(Stop The World),直到垃圾收集结束。
Serial Old 收集器(老年代:标记-整理算法):
Serial Old 收集器是 Serial 老年代版本,用于老年代 。采用的是 标记-整理算法。该收集器存在的主要意义是:在HotSpot虚拟机在客户端模式下使用。 当然如果在服务端模式下,它也可以有两种用途:
(1)在JDK5以及之前版本中与Parallel Scavenge 配合使用。
(2)作为CMS收集器发生失败时的后备。
ParNew 收集器(新生代):
ParNew 收集器本质上是Serial 收集器的多线程版本。同样可以使用控制参数(-XX:SurvivorRatio、-XX: PretenureSizeThreshold、-XX:HandlePromotionFailure。用于运行在服务端模式下和JDK7前大部分系统中新生代。除了Serial收集器外 只有 ParNew 收集器能与CMS 收集器配合使用。
Parallel Scavenge 收集器-吞吐量优先收集器( 新生代:标志-复制 ):
Parallel Scavebge 收集器也是一款新生代垃圾收集器,也是能够并行收集的多线程 基于 标志-复制 算法实现的收集器。与 ParNew 相似。Parallel Scavenge 的目标是达到一个可控的吞吐量。并提供了两个参数分别用于控制最大垃圾收集停顿时间和直接设置吞吐量大小:
(1)-XX:MaxGCPauseMillis: 控制最大垃圾收集停顿时间参数,是一个大于0的毫秒数。收集器将尽力保证内存回收时间不超过设置时间。
(2)-XX:GCTimeRatio:该参数表示垃圾收集时间占总时间的比率。相当于吞吐量的倒数。
(3)-XX:+UseAdaptiveSizePolicy:该参数被激活后,就不在需要人工指定新生代(-Xmn)、Eden与Survivor区 的比例(-XX:SurvivorRatio)、晋升老年代对象大小(-XX:PretenureSizeThreshold)等细节参数,虚拟机会根据当前系统的运行状况收集性能监控信息,从而动态的调整这些参数壹提供最合适的停顿时间或者最大吞吐量。该调节方式为自适应调节策略。
Parallel Old 收集器(老年代:标记-整理算法):
Parallel Old收集器是 Parallel Scavenge 收集器的老年代版本。是基于标记-整理算法实现的支持多线程并发收集器。该收集器在JDK 6 时才提供。在注重吞吐量和或者处理器资源为稀缺资源时,可以优先考虑 Parallel Scavenge 和 Parallel Old 收集器配合使用。
CMS(Concurrent Mark Sweep)收集器(老年代:标记-清除算法):
CMS 收集器是一种以获取最短回收停顿时间为目标的收集器。也称并发低停顿收集器。
缺点:
(1)对处理器资源敏感,但在并发阶段,它虽然不会导致用户线程停顿,但却会因为占用了一部分线程(或者说处理器的计 算能力)而导致应用程序变慢,降低总吞吐量。
(2)无法处理浮动垃圾,可能出现“Con-current Mode Failure” 失败进而导致一次完全的 ‘“STW” ,从而导致FullGC 的产生。
(3)会产生大量的空间碎片,产生不连续的空间。当分配大对象时,因为找不到足够大的连续空间,不得不提前触发一次FullGC。为了解决这个问题, CMS收集器提供了一个-XX:+UseCMS-CompactAtFullCollection开关参数(默认是开启的,此参数从 JDK 9开始废弃),用于在CMS收集器不得不进行Full GC时开启内存碎片的合并整理过程,由于这个 内存整理必须移动存活对象是无法并发的。这样空间碎片问题是解决了,但停顿时间又会变长,因此虚拟机设计者们还提供了另外一个参数-XX:CMSFullGCsBefore- Compaction(此参数从JDK 9开始废弃),这个参数的作用是要求CMS收集器在执行过若干次(数量 由参数值决定)不整理空间的Full GC之后,下一次进入Full GC前会先进行碎片整理(默认值为0,表 示每次进入Full GC时都进行碎片整理)。
Garbage First(G1) 收集器(整体:标记-整理算法,局部:标记-复制算法):
G1 收集器开创了面向局部收集的设计和 基于Region的内存布局形式。JDK7 的重要特性。并且于JDK7 Update 4 才正式商用。到了JDK8 Update 40 时 提供了并发卸载类的支持。在JDK9 时成为服务端模式下的默认收集器。
优点:
(1)可以指定最大停顿时间
(2)分Region的内存布局
(3)按收益动态确定回收集
缺点:
(1)内存占用高:虽然G1和CMS都使用卡表来处理跨代指针,但G1的卡表实现更为复杂,而且 堆中每个Region,无论扮演的是新生代还是老年代角色,都必须有一份卡表,这导致G1的记忆集(和 其他内存消耗)可能会占整个堆容量的20%乃至更多的内存空间;相比起来CMS的卡表就相当简单, 只有唯一一份,而且只需要处理老年代到新生代的引用,反过来则不需要,由于新生代的对象具有朝 生夕灭的不稳定性,引用变化频繁,能省下这个区域的维护开销是很划算的
(2)执行负载高:
目前在小内存应用上CMS的表现大概率仍然要会优于G1,而在大内存应用上G1则大多能发挥其 优势,这个优劣势的Java堆容量平衡点通常在6GB至8GB之间
网友评论