我试图调整某种高负载应用程序,通过一些预处理将数据从一个云流式传输到另一个云。 我的应用程序的具体内容是大量内存使用和低CPU消耗。 我用jconsole监视应用程序,并得到了一些有趣的图片 - cpu加载高达15%,我仍然可以捕获内存不足错误。
手动触发"执行GC"来自jconsole正在清理所有代中的大量内存,因此我假设应用程序中没有内存泄漏。
我的应用程序在mesos / marathon上运行,所以我尝试在单个虚拟CPU和多CPU之间切换各种GC(-XX:+ UseG1GC; -XX:+ UseParallelGC而不进行其他调整),图片实际上是相同的;
答案 0 :(得分:2)
当需要应用程序释放内存时,GC会运行。 GC是昂贵的操作,只有在需要时它才会运行。 我不确定您为什么要尝试将CPU利用率与运行GC相关联。 CPU利用率与运行GC应用程序无关。 如果VM线程决定GC运行它将暂停所有运行的应用程序线程(Safepointing)并允许GC执行操作,因此使用的CPU数量保持不变,无论您剩余多少CPU。
有许多GC标记可用于微调您的应用程序,我将无法建议任何不确定您的应用程序是什么?
以下链接可能会对您有所帮助 http://www.cubrid.org/blog/dev-platform/how-to-tune-java-garbage-collection/ https://confluence.atlassian.com/enterprise/garbage-collection-gc-tuning-guide-461504616.html
你应该知道你在哪里获得OOM,老一代,Metaspace,Codegen或基于你可以使用堆选项微调的本机
答案 1 :(得分:1)
我想我应该分享调查结果。
"内存不足" - 是我从DevOps-guy得到的,我想到的第一件事--OutOfMemoryException。所以,感谢Alex clarifying question。
在我的情况下,底层操作系统的Docker环境中是OOMKill。我为容器分配了1G并限制了736m的java堆大小。 但我的应用程序使用了netty,它分配了自己的内存缓冲区绕过堆。因此,当更多的连接出现时,netty分配了更多的直接缓冲区,这导致OOMKill尽管堆积健康。