Java 有人发现垃圾收集调优很有用吗?

Java 有人发现垃圾收集调优很有用吗?,java,garbage-collection,performance,Java,Garbage Collection,Performance,我读过很多关于在Java中调优GC的文章,经常想知道有多少人真正使用了一些更高级的特性 我总是尽可能避免调优,而是专注于编写尽可能简单的代码(Brian Goetz的建议)——到目前为止,这似乎对我很有效 这些调优策略是否具有跨VM版本更改的弹性,还是需要不断地重新评估 我使用的一个调优是-server标志。我不得不说,我自己不太需要使用调优。但我与那些编写延迟非常关键的代码的人密切合作:他们充分利用了这种调优——指定使用哪种GC算法、最大暂停时间、存活率等等 因此,我想答案是:如果延迟对应用程

我读过很多关于在Java中调优GC的文章,经常想知道有多少人真正使用了一些更高级的特性

我总是尽可能避免调优,而是专注于编写尽可能简单的代码(Brian Goetz的建议)——到目前为止,这似乎对我很有效

这些调优策略是否具有跨VM版本更改的弹性,还是需要不断地重新评估


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

我不得不说,我自己不太需要使用调优。但我与那些编写延迟非常关键的代码的人密切合作:他们充分利用了这种调优——指定使用哪种GC算法、最大暂停时间、存活率等等


因此,我想答案是:如果延迟对应用程序至关重要,那么您可能需要考虑调整GC,我当前工作的一部分是维护和提供一个大型java应用程序,该应用程序设计为使用大量内存(目前约为8GB)运行,这主要是由于正在使用大量缓存数据进行计算。我使用标准GC设置进行了初始部署,主要是因为没有一种简单的方法来模拟全速运行的生产环境

在接下来的几个月里,我分阶段定制了GC设置。一般来说,最大的可用旋钮似乎是调整增量gc的频率和幅度-最大的改进是用较小和更频繁的周期gc替换较大的周期gc。但我们确实看到了性能的提高

我不会发布我的特定设置,因为a)它们特定于我们的设置,b)因为我手边没有它们:)。但总的来说,我发现

  • 在这方面已经做了很多工作 调整默认gc设置。 几乎总是默认值比我所做的任何调整都好
  • 至少对我来说,在什么情况下 gc调优实际上是值得的 这是非常极端的 试图模仿是不合理的 他们,所以我不得不这么做 实验性的和递增的

上一篇文章的好参考。stackoverflow讨论。

绝大多数开发人员将永远不必(或想要)调优GC。我曾与不得不对其进行调整的人共事,以下是建议:

在您尝试调整垃圾之前 催收员100%确保您有 已验证,使用探查器。是什么 继续。一旦你开始调整,你就可以 确定要用探查器验证 它产生了积极的影响

您还应该对运行的每个版本的VM重新进行更改(不同的VM将有不同的调优策略)


我曾经帮助过有GC问题的人,结果证明他们没有关闭JDBC结果集(或者类似的问题)。这导致内存永远无法释放(他的代码出于某种原因保留在内存上)。解决这个问题使程序从20分钟延长到30秒或几分钟左右。内存使用率也下降了。

我认为最常见的调整是最大内存大小。大多数其他内存选项都有合理的默认值,并且经常被过度调优。i、 当它真的没有多大区别时设置。我经常看到人们设置了很多选项,但在任何情况下都有一半是默认选项


使用探查器是改善GC行为(通过减少创建的对象数量)的最有用的方法。

我有过,但不是最近。我正在开发的应用程序是实时渲染由单个运动JPEG图像构成的视频流。当时(大约是JDK 1.2和1.3),Xincgc的
-Xincgc
设置会将客户机垃圾收集器从更大的清理模式切换到定期清理少量垃圾的模式。因此,帧延迟的分布要低得多,给人的印象是更平滑的视频(而不是1-2-3暂停,1-2-3暂停)

我已经很长一段时间没有看过这些代码了,但我强烈怀疑,使用现代垃圾收集算法,
-Xincgc
实际上会降低性能


在当今世界,我要说的是,标准优化怀疑论应该始终适用:概要。你确定瓶颈真的是垃圾收集器吗?

简言之,是的,它对于调优任何严肃的Java应用程序都非常有用。我们经常发现,在生产场景中,稳定的应用程序和完全不可预测的应用程序之间存在差异。这当然不是我做的第一件事,但一旦你有一个应用程序在工作,并且可以对它应用真正的负载,这是在这一点上首先要调查的事情之一

我不确定大多数人是否会将Xmx参数设置为“调优”GC。我有点不同意。如果你有一个忙碌的盒子,并且分配了太多的内存,这可能会导致盒子交换太多内存。好的方面是,使用-mx可能不会被认为是GC调优,但它通常是你需要做的唯一正确的事情。正如@Fortyrunner指出的,您不希望它太大或太小。我发现如果可以的话,您不希望JVM使用多个内存库。请注意,如果您实际在服务器上部署,那么-server标志通常是不必要的。JVM将检测它在什么样的环境中运行。这在Windows上不起作用。不过,它在Linux和Solaris上也可以工作。大多数Windows机箱超过了标准服务器要求。假设它们将用于客户端使用,这就是我所关心的。每当JVM发布时,甚至在整个开发周期的固定时间间隔内,都需要检查任何调优策略——这就是我避免调优的原因。VM是不稳定的,它们会随着每个发布对GC进行更改/改进,所以即使是关于performan的“都市传奇”