我必须处理的一个应用程序定期使用ProcessBuilder
启动shell帮助程序。由于无法解释的原因,它仍然运行在32位JVM(Sun,1.6.0.25)上,即使底层操作系统是64位(RHEL 5.x也是如此)。
此应用程序内存满意,因此堆大小设置为最大3 GB,permgen为128 MB。
然而......随机时刻,shell助手无法启动。不是因为OutOfMemory,而是ENOMEM ......我能看到的唯一原因是缺少地址空间。
嗯,当然,但是在同一时刻,内存并没有真正承受压力,top
报告JVM的实际内存使用量及其虚拟集大小甚至不是3 GB ... < / p>
看看Process
代码的内容,我看到核心方法被称为forkAndExec()
,这几乎是自我解释的......根据我所知道的两个系统调用,它不应该失败。但确实如此。并非总是如此。
为什么?
编辑:应该注意使用neo4j。它似乎使用了很多FileChannel,这可能是缺少地址空间的原因吗?
答案 0 :(得分:1)
我认为你被Linux memory overcommits killing your processes.感染了。那篇博客文章提出了一个你可以调整的sysctl变量。
答案 1 :(得分:1)
我会减少堆大小。实际使用的堆量可能会为分叉进程留下越来越少的空间(它从其父进程继承资源)
很有可能只是升级到64位JVM才能解决问题,你能不能尝试64位Java 6更新(只是为了看看它是否能解决问题)如果有或没有,它应该告诉更多关于原因是什么(然后你可以决定它是否值得转换)