有一个 java 服务器端应用程序。线程数高达1000。该应用程序强烈使用NIO进行通信,JINI等。
您是否认为每分钟分配/取消分配 400 兆字节对于 java 应用程序来说是好的(可接受的)?
提出这个问题的原因 - 随着时间的推移,可用内存量变得越来越少:存在一些内存泄漏(每天几兆),使用的内存量也取决于要做的工作量(应用程序缓存了一些东西)。因此,可能存在 <= 100 兆可用内存的情况。GC 当然会变得疯狂,因为它的活动变得非常需要。(建议重启运行时间为生产中的一个月)
有一个 java 服务器端应用程序。线程数高达1000。该应用程序强烈使用NIO进行通信,JINI等。
您是否认为每分钟分配/取消分配 400 兆字节对于 java 应用程序来说是好的(可接受的)?
提出这个问题的原因 - 随着时间的推移,可用内存量变得越来越少:存在一些内存泄漏(每天几兆),使用的内存量也取决于要做的工作量(应用程序缓存了一些东西)。因此,可能存在 <= 100 兆可用内存的情况。GC 当然会变得疯狂,因为它的活动变得非常需要。(建议重启运行时间为生产中的一个月)
400 MB/秒的垃圾是非常糟糕的。
400 MB/分钟的垃圾对于您的应用程序来说可能是可以的。
我会尝试将 Eden 大小-XX:NewSize=
增加到 1g、2g 或 4g,看看这是否会提高性能。
如果这比您拥有的 CPU 数量多,我会尝试估计您拥有的活动线程数。
线程数最多为 1000。
这可能太多了,IMO。根据您的平台和-Xss
.
您是否认为每分钟分配/取消分配 400 兆字节对于 java 应用程序来说是好的(可接受的)?
那应该不是问题。事实上,从性能图来看,GC 看起来只是 CPU 时间的一小部分……而这只是可用时间的一小部分。
问这个问题的原因 - 随着时间的推移,可用内存量变得越来越少:存在一些内存泄漏(每天几兆),
好吧,您应该考虑追踪并修复这些泄漏。
... 使用的内存量也取决于要做的工作量(应用程序缓存一些东西)。
答案可能是增加堆大小。而且(令人惊讶的是)增加堆大小可以减少垃圾收集所花费的时间百分比。(虽然并发收集器和非常大的堆可能存在问题......)
因此,可能存在 <= 100 兆可用内存的情况。GC 当然会变得疯狂,因为它的活动变得非常需要。
是的。这很可能是您的存储泄漏的结果,而不是高分配率。随着 JVM 越来越接近 Heap 耗尽,GC 将花费越来越多的总时间来运行。这是不可避免的。(GC 大部分时间都在处理不是垃圾的对象。随着可回收空间的比例下降,回收该空间的成本会上升。)
有一个以-XX:+UseGCOverheadLimit
JVM 开关的形式解决此问题的方法。这使用了“在抛出 OutOfMemory 错误之前限制虚拟机在 GC 中花费的时间比例的策略”。. 基本上,它导致不可避免的 OOME在您的服务器陷入性能不断下降的死亡螺旋之前被抛出......
(建议重启运行时间为生产中的一个月)
...或修复内存泄漏!!!