有人发现垃圾回收调优有用吗?

21

我读过很多关于Java中调整垃圾回收的文章,经常想知道有多少人真正使用了一些更高级的特性。

我一直尽可能避免调优,并集中精力编写最简单的代码(Brian Goetz的建议)- 这似乎对我至今有效。

这些调优策略是否能够跨VM版本保持稳健,还是需要不断重新评估?

我使用过的一个调优策略是 -server 标志。


请注意,如果您实际上是在服务器上部署,则“-server”标志通常是不必要的。JVM将检测其运行环境的类型。 - oxbow_lakes
1
这在Windows上不起作用。但它可以在Linux和Solaris上运行。大多数Windows机器超出了标准的-server要求。假设它们将用于客户端使用。 - Fortyrunner
6个回答

21

我的工作职责之一是维护一个大型Java应用程序,该应用程序被设计为需要大量内存(目前约8GB),主要是由于进行了许多具有缓存数据的持续计算。我最初使用了标准的GC设置进行部署,主要是因为没有简单的方法来模拟完全运行的生产环境。

在接下来的几个月中,我分阶段定制了GC设置。通常,最大的可用旋钮似乎是调整增量GC的频率和幅度-最大的改进是将大的周期性GC与更小且更频繁的GC做出权衡。但我们确实能够看到性能提升。

我不会发布我的具体设置,因为a)它们是特定于我们的设置的,b)因为我手边没有它们:)

但总的来说,我的发现是:

  • 已经有很多工作在调整默认的GC设置。
  • 至少对我而言,需要进行GC调整的情况都极端到无法尝试模拟,因此我必须通过实验逐步进行。

这里是一个来自先前stackoverflow讨论的好参考。


11

绝大多数开发人员不需要(或不想)调整GC。我曾与那些必须调整它的人一起工作,以下是建议:

在尝试调整垃圾回收器之前,务必使用分析器100%验证正在发生的情况。一旦开始调整,请务必使用分析器验证它是否产生了积极的影响。

您还应该在每次运行不同VM版本时重新审查更改(不同的VM将具有不同的调整策略)。

我曾帮助某人解决过一个GC问题,后来发现这是由于他们没有关闭JDBC结果集(或类似问题)导致的。这会导致内存永远不会被释放(他的代码出于某种原因将它们保留下来)。修复该问题使程序从20分钟变为了30秒或几分钟左右。内存使用情况也大大降低。


这就是我所关心的。任何调优策略都需要在每次JVM发布时进行检查,甚至在整个开发周期中定期进行检查 - 这就是为什么我避免调优的原因。 - Fortyrunner
虚拟机是易变的,每次发布都会对垃圾回收进行改进,所以即使听到关于性能改进的“传说”,很可能在你听到它们时已经过时了...始终保持代码整洁,它很可能已经足够快了,如果不够快,加速它也会更容易。 - TofuBeer

8

我必须说,我自己并没有太多使用调优的需求。但是我与那些编写对延迟非常敏感的代码的人密切合作:他们经常使用这种调优——指定要使用哪个GC算法、最大暂停时间、幸存者比例等。

因此,我想答案是:如果应用程序对延迟非常敏感,您可能需要考虑调整您的GC


3
我认为最常调整的是最大内存大小。其他大多数内存选项都有合理的默认值,通常过度调整。即在实际情况下设置并没有太大的区别。我经常看到人们设置了很多选项,而其中一半在任何情况下都是默认值。;)
使用分析器是改善GC行为(通过减少创建对象的数量)最有用的方法。

我不确定大多数人会认为设置Xmx参数是GC“调优”。 - oxbow_lakes
我有些不同意。如果你有一个繁忙的盒子并分配了太多的内存 - 这可能会导致盒子过度交换内存。 - Fortyrunner
1
好的一点是,使用-mx可能不被视为GC调优,但通常这是你需要正确处理的唯一事情。正如@Fortyrunner指出的那样,你不希望它太大或太小。我发现如果可能的话,你不希望JVM使用超过一个内存银行。 - Peter Lawrey

3
我以前做过这方面的工作,但是已经有一段时间了。我所涉及的应用程序是实时渲染由单个动态JPEG图像构成的视频流。当时(大约在JDK 1.2和1.3左右),-Xincgc设置会将客户端垃圾回收器从更多的大爆炸式清理切换到定期清理一些垃圾的模式。因此,帧延迟的分布要低得多,给人以更平滑的视频印象(而不是1-2-3-暂停,1-2-3-暂停)。
我很久没有看过那段代码了,但我强烈怀疑,在现代垃圾回收算法下,-Xincgc实际上会降低性能。
在今天的世界里,我认为标准的优化怀疑主义应该始终适用:进行性能分析。您确定瓶颈真的是垃圾回收器吗?

它可能会降低整体性能,但仍然可以大大提高延迟。例如,C++的shared_ptr引用计数可能比Java GC慢,但总体效果却更加平滑 - Zan Lynx
@Zan,我不认为我理解你的评论。我的意思是-Xincgc现在太天真了。现代GC有更多有用的选项。我甚至不会得出结论,-Xincgc会导致更平滑的延迟,没有测试的情况下。 - Bob Cross
我的评论的重点是,持续进行小的清理可能会使应用程序运行时间更长,但如果应用程序是用户交互的,则使用起来会更加愉悦。 - Zan Lynx
@Zan,是的,那绝对是真的。话虽如此,我认为使用现代GC算法,你会发现比旧的-Xincgc更流畅且运行速度更快。 - Bob Cross

2

简而言之,是的,它对于优化任何严肃的Java应用程序非常有用。我们经常发现,在生产场景中,这是一个稳定应用程序和完全不可预测应用程序之间的区别。当您有一个运行良好的应用程序并可以为其应用真正的负载时,它肯定不是我要做的第一件事情,但此时它是要调查的第一件事情之一。


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