Java GC线程瓶颈在实践中是否存在?

4
Java的并行收集GC在多线程环境下的优化程度如何?我编写了一些多线程Jython代码,其中大部分时间都在调用Java库。根据我运行程序时使用的选项不同,库调用要么在内部进行大量分配,要么几乎没有分配。当我使用需要大量堆分配的选项时,代码无法扩展到超过6个核心。当我使用不需要大量分配的选项时,它可以扩展至少20个核心。考虑到我使用的是Sun VM、并行GC和Jython作为我的粘合语言,这是否与GC瓶颈有关呢?
编辑:仅澄清一下,我不一定会想到对于Java老手来说很显然的东西,因为我几乎从不使用Java/JVM语言。我大部分时间都在D语言和Python的CPython实现中进行编程。我正在使用JVM和Jython进行一个小型的一次性项目,因为我需要访问Java库。

1
你使用了哪些选项?这似乎是一个线程池问题,而不是垃圾回收问题。 - Thierry Roy
@Thierry:这些选项是针对我的程序特定的,涉及到调用哪些库函数。我甚至没有使用线程池。 - dsimcha
4个回答

3

由于您的问题涉及GC瓶颈:您可以通过打开GC日志并检查日志来消除这种可能性,如果有大量带有大暂停的GC事件,则可以确认/排除此理论。(但是,在您描述的情况下,我猜测这不是一个GC问题)。


谢谢,你指出并让我搜索到了获取 GC 执行日志的方法,让我知道原来这一步是如此容易。在 D 语言中并不容易,而且据我所知,在 CPython 中也不容易。这些日志确实澄清了一个事实:GC 每秒运行多次。我很惊讶代码能够扩展得如此之好。 - dsimcha

2
对我来说,GC和多线程问题非常真实。我并不是说JVM不好,而是这个问题本身很难处理。
在我们的一个项目中,我们有两个应用程序在单个JVM(应用服务器)上运行。当单独测试它们时,这是可以接受的,但是当两者同时进行压力测试时,性能会以奇怪的方式下降。最终我们将应用程序拆分为两个JVM,并且性能恢复正常(当然比只使用一个应用程序时慢,但是还算合理)。
调整GC非常困难。事情可能会在5分钟内得到改善,然后一个主要的集合将被阻止等等。您可能会决定您想要高吞吐量或低操作延迟。高吞吐量对于批处理很好,低延迟对于交互式应用程序是必需的。最终,JVM的默认参数对我们来说是给出最佳结果的!
这不是一个真正的答案,而是经验的回报,但是对我来说,GC和多线程可能是一个问题。

我知道GC /多线程问题存在,但Java的GC非常完善,并从Java作为一种语言的严格性中获益(没有联合,原始指针等),以至于我认为这些问题基本上已经解决了。在D中,问题甚至更大,但由于我通常编写更多的“从头开始”的代码,而不是粘贴代码,在D中可以做更多的肮脏技巧来避免不必要的分配,因此它们也更容易被解决。在当前项目中解决它们基本上意味着重写一个大型库。 - dsimcha

1
Java的垃圾回收器是分代的。第一代集合旨在处理短寿命对象,并且预计经常运行。如果有许多短寿命分配,则每秒运行几次短时间间隔是预期的行为。(这应该是评论而不是答案-我没有声望,抱歉)。
此外,根据您使用的VM,可以选择GC算法。选项将根据您使用的VM版本和供应商而异。
这里有一些(旧的)信息:http://java.sun.com/developer/technicalArticles/Programming/turbo/#The_new_GC

0

线程性能可能因jdk版本而异。根据我的经验,在jdk6u18上,启用-XX:+UseParallelGC(而不是并发标记扫描gc)的并行gc在具有数百个非常活跃的线程的四核处理器上表现非常出色。我认为它很难想象它不能扩展到6个核心以上。

Sun硬件基于高核心处理器的事实解释了为什么他们近年来在新垃圾收集器方面投入了大量精力。

并行gc未默认启用,因为其单线程性能不如默认gc。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接