我不确定 Parallel GC 使用哪个收集器来收集永久空间?
离开this 页面,如果您使用并行 GC,则并行清除收集器用于年轻代,并行标记/清除收集器用于老一代(也称为终身代)。所以我猜答案是“Parallel GC 用于 Parallel GC 的永久空间收集”。有点循环的说法,但我认为这是有道理的。
我也想不出可以接受长时间停顿的应用程序(会导致响应速度降低)。任何人都希望减少 GC 的停顿并让应用尽可能地响应。
“长时间停顿”是相对的,是否可以接受取决于应用程序的类型及其用途。需要快速用户交互的应用程序,例如游戏,可能需要较短的暂停时间,而长时间运行的应用程序几乎没有用户交互(夜间批处理作业、可以运行几天的处理作业,可能是长时间运行的服务器时间段等),或者不需要快速用户交互(文字处理器?但是谁用Java编写文字处理器?)不会有几乎那么严格的暂停要求,所以暂停将是对那些没问题。此外,暂停不是唯一需要考虑的 GC 因素,因此即使暂停是可以的,也有其他原因会选择暂停时间更长的 GC。我会在下面进一步解释。
我的问题是大多数 Web 应用程序不应该因为它的响应性而使用并发标记扫描 (CMS) 收集器吗?
CMS 收集器有缺点。在你提到的文章中,有这样一行:
通常并发低暂停收集器不会复制或压缩活动对象。在不移动活动对象的情况下完成垃圾收集。
因此,没有堆压缩会导致堆碎片,这可能会损害性能。 This 帖子指出了另一个缺点(我不确定这篇帖子到底有多可靠,但乍一看似乎还不错):
CMS 收集器的一个更重要的缺点与它在老年代堆满时无法启动有关。一旦老年代满了,CMS 就太晚了,它必须回退到通常的 stop-the-world 策略(通过 GC 日志中的“并发模式失败”来宣布)。
...
然而,CMS 的最大缺点与它不压缩老年代堆有关。因此,随着时间的推移,它存在堆碎片和严重操作退化的风险。
...
很明显,通过这些设置,JVM 在负载测试条件下运行了将近 14 个小时(在生产环境和较低负载下,这个危险的良性时期可能会持续更长的时间)。然后突然有很长的 GC 暂停,实际上停止了 JVM 大约一半的剩余时间。不仅有超过 10 秒的老年代清理混乱的尝试,甚至新生代 GC 暂停也在秒范围内,因为收集器在尝试清理老年代时花费了大量时间来寻找空间。将对象从新代提升到老代。
博文中有更多详细信息,您可能应该阅读它,因为这里的引文之外还有很多内容以及一些精彩的演示。但要指出的是,CMS 收集器并不是万能的收集器。它也有缺点,这可能会导致程序员选择不同的收集器。使用它作为默认值对于短期运行的应用程序可能是可以的,但对于长时间运行的应用程序,这种行为会非常糟糕......
此外,我认为如果我们将 CMS 收集器和并行收集器一起使用,其中 CMS 用于老年代和并行 fpr 新生代,应用程序会是最好的
当您将-XX:+UseConcMarkSweepGC 参数传递给您的VM 时,这实际上是默认模式。但如上所述,您可能需要真正花一些时间来考虑要使用的收集器。在不考虑您的用例的情况下选择收集器可能不是一个好主意。 (旁注:我以为我从 Oracle 看到了一些关于如何决定使用什么 GC 的文档,但我再也找不到它了......)
此外,如果您有 Java 7u4 或更高版本,您可能需要考虑使用闪亮的新 G1 收集器。它应该是 CMS 收集器的替代品。