我们最近开始偶尔使用有关“java.lang.OutOfMemoryError:请求8589934608字节的Chunk :: new。Out of swap space?”消息开始崩溃的应用程序。Java JIT编译器导致OutOfMemoryError
我环顾四周,在网络上,到处都建议只限于
- 恢复到以前的版本的Java
- 小提琴与内存设置
- 使用客户端而不是服务器模式
恢复到以前的版本意味着新的Java有一个错误,但我没有看到任何迹象。记忆根本不是问题;服务器有32GB可用,并且Xmx设置为20,而Xms是10.我看不到剩余12GB的JVM耗尽(减少给予机器上其他几个进程的量)。由于应用程序和环境的特性,我们坚持使用服务器模式。
当我查看应用程序的内存和CPU使用情况时,我发现整天的内存使用量不断增加,但在使用之前突然发生CPU使用率高达100%,内存使用量从X增加到X + 2GB,到X + 4GB,到(有时)X + 8GB,到JVM死亡。这似乎是在JIT编译中可能发生循环重复数组大小调整。
我现在看到上述8GB请求和16GB请求发生错误。所有时候,这种情况发生时编译的方法都是一样的。这是一个简单的方法,它具有非嵌套循环,没有递归,并且使用方法直接返回静态成员字段或实例成员字段,计算量很少。
所以我有2个问题:
- 没有任何人有什么建议吗?
- 我可以测试在测试环境中是否存在编译此特定方法的问题,而不运行整个应用程序,直接调用JIT编译器?或者我应该启动应用程序,并告诉它编译方法后小得多的调用计数(如2),迫使它编译方法几乎立即而不是在一天的随机点?
@StephenC
JVM是1.6.0_20(先前1.6.0_0),在Solaris运行。我知道这是由于几个原因导致问题的汇编。
- 在导致它的秒
ps
示出与对应于编译器线程(从jstack)ID的Java线程占用了100%的CPU时间 jstack
示出了问题是JavaThread "CompilerThread1" daemon [_thread_in_native, id=34, ...]
jstack
中提到的方法总是一样的,而且是我们写的。如果您看到示例jstack
输出,您将知道我的意思,但出于显而易见的原因,我无法提供代码示例或文件名。我会说这是一个非常简单的方法。 Essentiall少数空检查,2 for循环进行平等检查并可能分配值,以及一些简单的方法调用之后。总共可能有40行代码。
尽管应用程序每天运行并且每天都重新启动,但该问题在两周内发生过两次。此外,这些应用程序在这些时间都没有承受重负。
如果您说出您正在使用的JVM版本和补丁级别(以及之前的内容)以及您的操作系统/硬件平台是什么,这将会很有帮助。另外,为什么你在JIT编译期间得出结论:问题是如何发生的,你如何计算出正在编译的方法......以及方法的代码是什么样的。 – 2010-08-11 08:59:28
您是否找到满意的解决方案? – 2015-01-01 17:48:00
对不起*非常*迟到的回复 - 我已经标记了答案 – Phil 2015-03-15 12:06:03