对于java gc,300-400 MB / min的alloc / dealloc速率是否正常?

时间:2012-10-10 12:51:05

标签: java garbage-collection heap visualvm

有一个java服务器端应用程序。线程数最多为1000.该应用程序强烈使用NIO进行通信,JINI等。

您是否会考虑为一个Java应用程序分配/取消分配每分钟400兆字节(可接受)?

提出这个问题的原因 - 随着时间的推移,可用内存的数量变少:有一些内存泄漏(每天几兆),使用内存的数量取决于要做的工作量(应用程序缓存一些事情)。因此可能存在< = 100兆的可用内存。 GC当然变得疯狂,因为它的活动变得非常需要。 (建议重启的运行时间是生产中的一个月)

Heap allocation statistic from VisualVM

2 个答案:

答案 0 :(得分:2)

400 MB /秒的垃圾非常糟糕。

400 MB / min的垃圾可能适合您的应用。

我会尝试通过-XX:NewSize=将Eden大小增加到1g,2g或4g,看看这是否会提高性能。

如果超过你拥有的CPU数量,我会尝试估计你有多少活动线程。

答案 1 :(得分:1)

  

主题号码最多为1000个。

这可能太多了,IMO。每个线程的堆栈最多可占用1Mb(或更多),具体取决于您的平台和-Xss

  

您是否会考虑为一个Java应用程序分配/取消分配每分钟400兆字节(可接受)?

那应该不是问题。实际上,查看性能图表时,GC看起来只占所用CPU时间的一小部分...... 只是现有的一小部分。

  

提出这个问题的原因 - 随着时间的推移,可用内存量会减少:有一些内存泄漏(每天几兆),

那么你应该考虑追踪并修复这些泄漏。

  

...也使用的内存量取决于要做的工作量(应用程序缓存一些东西)。

答案可能是增加堆大小。并且(令人惊讶地)增加堆大小可以减少垃圾收集所花费的时间百分比。 (虽然并发收集器可能存在问题而且堆积很大......)

  

因此可能存在< = 100兆的可用内存。 GC当然变得疯狂,因为它的活动变得非常需要。

是。这很可能是您的存储泄漏造成的,而不是高分配率。随着JVM越来越接近Heap,GC将占用总运行时间的比例越来越大。这是不可避免的。 (GC花费大部分时间处理非垃圾的物体。随着可回收空间的比例下降,回收该空间的成本上升。)

-XX:+UseGCOverheadLimit JVM切换的形式有一种解决方法。这使用“一种策略,该策略限制在抛出OutOfMemory错误之前在GC中花费的VM时间的比例。”。基本上,它导致不可避免的OOME被抛出之前你的服务器陷入了不断下降的性能死亡螺旋......

  

(建议重启的运行时间是生产中的一个月)

...或修复内存泄漏!!!