GC算法
Posted parkdifferent
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GC算法相关的知识,希望对你有一定的参考价值。
GC算法
- JVM提供了4中不同的算法执行GC
The serial garbage collector
- 串行垃圾收集器是四个中最简单的。 这个是默认收集器
如果应用程序运行在客户端类机器(Windows上的32位JVM或单处理器机)。 - 串行收集器使用单个线程来处理堆。 它将停止所有应用程序线程在处理堆时(对于minor GC或full GC)。 在full GC期间,它会完全压缩老年代。
- 串行收集器是系统默认的,通过指定其他GC算法禁用。
The throughput collector
- 这是服务器类机器的默认收集器(多CPU Unix机器,和任何64位JVM)。
- 吞吐量收集器使用多个线程来收集年轻代,与使用串行收集器相比,可以更快地 minor GC。 吞吐量collector也可以使用多个线程来处理老年代。
- 因为它使用多个线程,吞吐量收集器通常称为并行收集器
- 吞吐量收集器在minor GC和full GC期间停止所有应用程序线程,它在full GC期间完全压缩了老年代
- 因为它在大多数情况下是默认使用,因此不需要明确启用它。启用 -XX:+UseParallelGC
-XX:+UseParallelOldGC
The CMS collector
- CMS收集器旨在消除与吞吐量收集器和串行收集器相关的full GC长暂停。 CMS在minor GC期间停止所有应用程序线程,它也执行多个线程。 但值得注意的是,CMS使用不同的算法收集年轻代(-XX:+ UseParNewGC)比吞吐量收集器使用(-XX:+ UseParallelGC)
- CMS不停止应用程序线程在full GC期间,而是使用一个或多个后台线程定期扫描老年代并丢弃未使用的对象。 这使CMS成为低暂停收集器:应用程序线程仅暂停在minor GC期间,以及在某些非常短的时间内后台线程扫描老年代。 应用程序线程停止的总时间远小于吞吐量收集器。
- 这里的权衡是CPU使用率的增加:必须有足够的CPU可用于后台GC线程扫描堆,在应用程序线程正在运行时。 此外,后台线程不执行任何压缩操作(除了full GC期间),这意味着堆可能变得碎片化。 如果CMS后台线程没有足够的CPU来完成其任务,或者对于分配对象而言堆变为过于分散,CMS将恢复为串行收集器的行为:它会停止所有应用程序线程,以便清理和压缩老年代使用单线程。 然后它再次开始并发后台处理(直到可能,下一次堆变得太碎片了)
- 如果CMS后台线程在堆填满之前未完成扫描堆并释放对象,CMS将遇到并发模式失败。在那种情况下,CMS必须恢复执行full GC,所有应用程序线程停止。full GC执行只有一个线程,使其成为非常严重的性能损失
- 启用 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC (默认这2者都是false)
The G1 collector
- G1(或Garbage First)收集器旨在处理大堆(大于大约4 GB),暂停时间最短。 它将堆分成许多区域,但它仍然是分代收集器。 其中一些区域包括年轻代,并且仍然通过停止所有应用程序线程来收集年轻代并将所有活着的对象移动到老年代或 survivor 中。 如在其他算法中,这发生使用多个线程。
- G1是并发收集器:老年代由后台线程处理不需要停止应用程序线程来执行大部分工作。 因为
老年代分为不同区域,G1可以清理老年代的对象通过从一个区域复制到另一个区域,这意味着它(至少部分地)压缩堆在正常处理期间。 因此,G1堆受碎片影响的可能性要小得多 - 尽管仍有可能。 - 与CMS一样,避免full GC周期的权衡是CPU时间:多个后台必须有可用的CPU周期在应用程序线程运行时
- G1 也可能经历并发模式失败,可能性更小
- 启用 -XX:+UseG1GC (默认为false)
总结
- 四种可用的GC算法采用不同的方法最小化GC对应用程序的影响。
- 串行收集器有意义(并且是默认值)只在一个CPU可用,额外的GC线程会干扰应用程序。
- 吞吐量收集器是其他机器上的默认值; 它最大化应用程序的总吞吐量,但可能会受到个别操作长时间停顿的影响。
- CMS收集器可以并发收集老年代在应用程序线程运行时, 如果对于后台处理有足够的CPU可用,这可以避免full GC周期对应用的影响
- G1收集器也并发收集老年代在应用程序线程正在运行时,可能会避免full GC。 它的设计使其更少可能经历 full GC 比起 CMS。
以上是关于GC算法的主要内容,如果未能解决你的问题,请参考以下文章