垃圾收集器和性能在java中命中

时间:2013-05-01 15:30:12

标签: java performance tomcat garbage-collection

当我测试在tomcat中部署的应用程序时,该应用程序被挂起。并排我正在运行visualvm。在应用程序挂起期间,我在visualvm中看到垃圾收集正在进行中。我在理论上已经读过,当垃圾收集开始工作时,系统会停止,因为应用程序线程在这段时间内停止。

我希望得到清晰的想法

其他开发者如何处理这种情况?

如何在不影响系统性能的情况下以有效的方式处理它?<​​/ strong>

可以将其视为内置固有属性还是可以有其他有效的解决方案?

因为,JVM可以配置不同的垃圾收集器算法,但在某些时候它必须运行。如果我理解错了,请纠正我。

3 个答案:

答案 0 :(得分:4)

您的应用程序暂停,因为GC耗时太长。我建议您进行应用程序性能分析,并尝试理解为什么您的应用程序需要GC运行这么长时间。寻找不必要的分配,未使用的对象,在没有任何控制的情况下长大的集合。

我有时会遇到这个问题。该解决方案总是涉及基于应用程序性能分析的某种优化(我在不同场合使用过New Relic和AppDynamics)。

答案 1 :(得分:3)

首先回答您的主要问题:不,您不必接受您的应用程序挂起。你可以真正做点什么。但是,有许多方法可以通过调整代码和使用直接控制GC策略的JVM开关来微调垃圾收集器。然而,这是一个广泛的主题,没有一个单一的最佳答案。这取决于您的应用程序和您的环境。你能做的最好的事情就是教育自己,关于它:

1。)在此处获取概述:http://www.oracle.com/technetwork/java/gc-tuning-5-138395.html

2.)阅读具体的调整方案:

3.)阅读关于同一主题的其他SO问题。

以下是我在自己的代码中使用的一些规则:

  • 从不尝试通过“在适当的时候”手动调用System.gc()来改善GC行为。如果将此与GarbageCollectorMXBeanMemoryMXBean等内容结合使用,可以超越垃圾收集器。

  • 当我发现一个可重现的性能问题时,GC的责任(通常不是这种情况 - 几乎总是先调整其他东西),我会研究{{的子类的使用3}}帮助我在不同的GC运行之间分配负载,例如我会检查是否使用Reference而不是其他Map帮助。

  • 我只是采用JVM调优作为最后的手段。通常很难记录为什么以及如何使用-XX:MaxNewSizeWeakHashMap之类的参数,而且我真的不希望人们在供应链的下游开始尝试使用GC调整自己,而我却没有理解问题的根本原因。

  • 当我确实看不到其他选项时,我首先尝试使用-Xms-Xmx - 有时缩小堆大小提高垃圾收集性能,这也很容易解释。将起始堆大小设置为最大堆大小可确保新内存分配不会导致暂停 - 可能是重新排列堆内容。我使用的其他设置包括-XnoClassGC-XX:+UseTLAB

答案 2 :(得分:3)

有两种方法可以解决这个问题:

  • 您可以通过选择&#34;低暂停&#34;来调整JVM的垃圾收集子系统。收集器,和/或更改各种调整选项。不幸的是,低暂停收集会产生成本。减少GC运行时系统暂停的时间长度,但另一方面是垃圾收集和相关事情上花费了更多的CPU周期整体

  • 您可以调整应用程序以减少它创建的(长寿命)垃圾量以及泄漏的内存量。但是你也需要在这里小心......因为一些经典策略(对象池,基于弱/软引用的缓存)实际上可以使事情变得更糟。至少在尝试减少分配之前,您应首先进行分析。

还有其他可能的解释:

  • &#34;挂起&#34;可能是无关的。他们可能是因为谈论缓慢的外部资源。它们可能是导致线程瓶颈的不幸副作用。

  • &#34;挂起&#34;可能是整个系统造成的,并且会引起争议。当您尝试使用不符合物理内存的堆时会发生这种情况。然后,系统必须根据需要在物理内存和光盘之间交换虚拟内存页面。垃圾收集(特别是&#34;完全&#34; GC)很可能触发这一点。