使用并发标记扫描GC收集器



这个问题是基于我从链接的Java垃圾收集器一节的理解看起来jvm在windows 7上默认使用"并行GC",我确认了它-XX:+PrintCommandLineFlags -version。这篇文章还说

并行垃圾收集器使用多个线程执行年轻一代的垃圾收集。此收集器应在大量使用时使用工作需要完成,长时间的停顿是可以接受的

我不确定哪个收集器用于并行GC的年老空间收集?

我也想不出长时间的暂停是可以接受的应用程序(将导致更少的响应)。任何人都想减少GC的暂停,并使应用程序尽可能响应。

然后读取收集年老代的Concurrent Mark Sweep (CMS) Collector

CMS说it require low pause times and can share resources with the garbage collection

我的问题是不应该由于CMS收集器的响应速度快,大多数web应用程序都使用它。我相信一定还有其他因素导致决定,但通过这个链接后,我觉得我应该改变默认的GC类型并发标记扫描(CMS)收集器。有什么想法/见解吗?

进一步,我认为如果我们同时使用CMS收集器和并行收集器,其中CMS用于老一代和并行fpr,应用程序可以是最好的年轻一代

我不确定哪个收集器用于并行GC的年老空间收集?

离开此页,如果您使用并行GC,则并行清除收集器将用于年轻代,并行标记/清除收集器将用于老代(也称为年老代)。所以我猜答案是"并行GC被并行GC用于长期空间收集"。有点循环语句,但我认为它是有意义的。

我也想不出长时间的暂停是可以接受的应用程序(将导致更少的响应)。任何人都想减少GC的暂停,并使应用程序尽可能响应。

"长pause"是相对的,它们是否可以接受取决于应用程序的类型及其用途。需要快速用户交互的应用程序,例如游戏,可能需要较低的暂停时间,而长时间运行的应用程序,很少有用户交互(隔夜批处理作业,可以运行几天的处理作业,可能运行很长时间的服务器等),或者不需要快速用户交互(文字处理器?但是谁用Java编写文字处理程序呢?)不会有严格的暂停要求,所以暂停对这些程序来说是可以的。此外,暂停并不是要考虑的唯一的 GC因素,因此,即使暂停是可以的,也有其他原因可以选择具有较长暂停的GC。我以后再解释。

我的问题是,大多数web应用程序不应该使用并发标记扫描(CMS)收集器,因为它的响应性。

CMS收集器有缺点。在您提到的文章中,有这样一行:

通常并发低暂停收集器不会复制或压缩活动对象。垃圾收集在不移动活动对象的情况下完成。

因此,没有堆压缩将导致堆碎片,这可能对性能有害。这篇文章指出了另一个缺点(我不确定这篇文章到底有多可靠,但乍一看似乎相当不错):

CMS收集器的一个更重要的缺点是,当旧代堆已满时,它无法启动。一旦旧代已经满了,对于CMS来说就太晚了,它必须回到通常的停止世界策略(由GC日志中的"并发模式失败"宣布)。

然而,CMS的最大缺点与它不压缩旧代堆有关。因此,随着时间的推移,它会带来堆碎片和严重操作退化的风险。

很明显,在这些设置下,JVM在负载测试条件下工作了近14个小时(在生产环境中,在较低的负载下,这段时间可能会持续更长的时间)。然后突然出现了很长的GC暂停,这实际上使JVM停止了大约一半的剩余时间。不仅要尝试清理旧代中的混乱(持续时间超过10秒),而且即使是新一代GC暂停也在秒范围内,因为收集器在试图将对象从新代提升到旧代时花费了大量时间在旧代中搜索空间。

在博客文章中有更多的细节,你可能应该读一下,因为在引用之外有很多内容,还有一些很棒的演示。但是需要注意的是,CMS收集器并不是一个放之四海而皆准的收集器。它也有缺点,可能会导致程序员选择不同的收集器。对于短时间运行的应用程序,使用它作为默认值可能没问题,但对于长时间运行的应用程序,这种行为将非常糟糕…

进一步,我认为如果我们将CMS收集器和并行收集器一起使用,CMS用于老一代,并行fpr用于年轻一代,应用程序可以是最好的

这实际上是默认模式,当你传递-XX:+UseConcMarkSweepGC参数给你的VM。但是如上所述,您可能真的需要花一些时间来考虑要使用哪种收集器。在不考虑用例的情况下选择收集器可能不是一个好主意。(旁注:我认为我从Oracle看到了一些关于如何决定使用什么GC的文档,但我再也找不到它了…)

此外,如果您使用Java 7u4或更高版本,您可能需要考虑新的G1收集器。它应该是CMS收集器的替代品。

我不确定哪个收集器用于年老空间收集平行GC吗?

如果您没有指定标志"-XX:+UseParallelOldGC", jvm将根据机器上可用的内核数量,操作系统,32/64位等选择单线程或多线程收集器。

我的问题是大多数web应用程序不应该使用并发标记扫描(CMS)收集器,因为它的响应性。

CMS收集器的问题是,它没有老一代内存压缩导致内存分配的性能下降,并最终停止世界FULL GC与并行GC。

如果你的web应用程序使用一个小堆(4-5GB),而不是经常(每天1-2次)填充,并且可以接受1s/(旧的gen. GB)的暂停,那么并行GC是一个很好的选择。

如果您有较大的堆,CMS是一个更好的选择,因为它在收集旧代时不会引起长时间的停止世界暂停。但是无论如何,你应该安排一次FULL内存gc,比如每天一次,在非高峰时间,以便进行内存压缩。

进一步,我认为应用程序可以最好的,如果我们使用CMS收集器和并行收集器在一起,其中CMS用于老一代和平行FPR年轻一代

并行GC和CMS不能同时使用。但年轻一代的收集是平行的,并停止世界与两个收藏家。