使用Concurrent Mark Sweep GC Collector?

时间:2014-07-06 06:31:10

标签: java garbage-collection

这个问题是基于我对link的Java垃圾收集器部分的理解 看起来jvm默认使用Windows 7上的“Parallel 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

我的问题不应该是最重要的 Web应用程序使用Concurrent Mark Sweep(CMS)收集器因为它的响应能力。?我确信还必须有其他一些因素来使 决定但通过这个链接后,我觉得我应该将默认的GC类型更改为Concurrent Mark Sweep(CMS)收集器。有什么想法/见解吗?

此外,我认为如果我们将CMS收集器和并行收集器结合使用,CMS将用于老一代和并行fpr,那么应用程序可能是最佳的 年轻一代

2 个答案:

答案 0 :(得分:8)

  

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

离开this页面,如果使用并行GC,则并行扫描收集器用于年轻代,并行标记/扫描收集器用于老一代(也称为终身代)。所以我想答案是“并行GC用于并行GC的终身空间收集”。这是一个循环声明,但我认为这是有道理的。

  

此外,我无法想到可以接受长暂停的应用程序(会导致响应性降低)。任何人都希望减少对GC的停顿,并使应用程序尽可能地响应。

“长暂停”是相对的,它们是否可接受取决于应用程序的类型及其用途。需要快速用户交互的应用程序(如游戏)可能需要较短的暂停时间,而长时间运行的应用程序几乎没有用户交互(夜间批处理作业,处理可运行数天的作业,可能需要长时间运行的服务器一段时间,等等,或者不需要快速用户交互(文字处理器?但是谁用Java编写文字处理器?)不会有几乎同样严格的暂停要求,所以暂停将是好的,那些。此外,暂停不是要考虑的唯一 GC因素,因此即使暂停是正常的,还有其他原因可以选择具有较长暂停的GC。我会进一步解释。

  

我的问题是,大多数Web应用程序都不应该使用Concurrent Mark Sweep(CMS)收集器,因为它的响应能力。?

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

  

通常,并发低暂停收集器不会复制或压缩活动对象。无需移动活动对象即可完成垃圾收集。

因此,堆压缩不会导致堆碎片,这可能会对性能产生不利影响。 This帖子说明了另一个缺点(我不确定这篇文章到底有多可靠,但乍一看似乎相当不错):

  

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

     

...

     

然而,CMS的最大缺点是它不会压缩旧一代堆。因此,随着时间的推移,它会带来堆碎和严重操作降级的风险。

     

...

     

很明显,通过这些设置,JVM在负载测试条件下运行了近14个小时(在生产和负载较低的情况下,这种危险的良性时期可能持续更长时间)。然后突然有很长的GC暂停,实际上大约一半的剩余时间停止了JVM。不仅尝试清理老一代的混乱,持续时间超过10秒,甚至新一代GC暂停都在秒范围内,因为收藏家花了很多时间在老一代寻找空间时试图从新老代推广对象。

博客文章中有更多详细信息,您可能应该阅读,因为这里引用了很多内容以及一些精彩的演示。但要点的是CMS收集器不是一个适合所有收集器的收集器。它也有它的缺点,这可能会导致程序员选择不同的收集器。对于短期运行的应用程序,将它用作默认值可能没问题,但对于长时间运行的应用程序,这种行为会非常糟糕......

  

此外,我认为如果我们将CMS收集器和并行收集器结合使用,CMS将用于老一代和并行fpr年轻一代,那么应用程序可能是最佳的

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

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

答案 1 :(得分:1)

  

我不确定哪个收藏家用于终身空间收藏   并行GC?

如果没有指定标志“-XX:+ UseParallelOldGC”,jvm将根据机器上可用的内核数量,os,32/64位等选择单线程或多线程收集器。 / p>

  

我的问题是大多数Web应用程序都不应该使用Concurrent Mark   扫描(CMS)收集器,因为它的响应能力。?

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

如果你的网络应用程序使用的小堆(4-5GB)不能经常填充(每天1-2次)并且1s /(旧版GB)的暂停是可接受的,则并行GC是一个不错的选择。

如果你有更大的堆,CMS是一个更好的选择,因为它不会导致世界在收集老一代时暂停世界。但是无论如何你应该安排一个完整的记忆gc让我们说在非高峰时段每天一次,以便做记忆压缩。

  

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

无法将它们设置为一起使用:并行GC和CMS。但是年轻一代的收藏是平行的,并且与两个收藏家一起停止了世界。