有一个java服务器端应用程序。线程数最多为1000.该应用程序强烈使用NIO进行通信,JINI等。
您是否会考虑为一个Java应用程序分配/取消分配每分钟400兆字节(可接受)?
提出这个问题的原因 - 随着时间的推移,可用内存的数量变少:有一些内存泄漏(每天几兆),使用内存的数量取决于要做的工作量(应用程序缓存一些事情)。因此可能存在< = 100兆的可用内存。 GC当然变得疯狂,因为它的活动变得非常需要。 (建议重启的运行时间是生产中的一个月)
答案 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被抛出之前你的服务器陷入了不断下降的性能死亡螺旋......
(建议重启的运行时间是生产中的一个月)
...或修复内存泄漏!!!