我正在运行javajava -Xmx240g mypackage.myClass
操作系统是 Ubuntu 12.10。
top
说MiB Mem 245743 total
,并表明 java 进程virt 254g
从一开始就有,并且res
正在稳步增长到169g
. 那时它看起来好像开始了很多垃圾收集,我认为是因为该程序当时是单线程的,并且CPU%
大部分100%
时间都到了这一点,并且此时它在 1300-2000 左右跳跃(我的结论是多线程垃圾收集器),然后res
慢慢移动到172g
. 那时java崩溃了
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
在与new double[2000][5]
java -version
说
java version "1.7.0_15"
OpenJDK Runtime Environment (IcedTea7 2.3.7) (7u15-2.3.7-0ubuntu1~12.10)
OpenJDK 64-Bit Server VM (build 23.7-b01, mixed mode)
硬件是 Amazon cr1.8xlarge 实例
在我看来,即使有大量可用内存,java 也会崩溃。这显然是不可能的,我必须把一些数字解释错。我应该在哪里查看以了解发生了什么?
编辑:
我没有指定任何 GC 选项。唯一的命令行选项是-Xmx240g
我的程序成功地处理了许多输入,并且top
有时说它使用了高达 98.3% 的内存。但是,我通过某些程序输入重现了上述情况。
编辑2:
这是科学应用。它有巨大的树(1-10 百万个节点),在每个节点中有几个double
大小约为的数组。300x3 - 900x5。初始树创建程序后不会分配太多内存。大多数时候,这些数组都会进行一些算术运算。
编辑3:
HotSpot JVM 以同样的方式死机,在 170-172g 标记处大量使用 CPU,并因同样的错误而崩溃。看起来 70-75% 的内存是 JVM 不想跨越的一条神奇线。
最终解决方案:使用 -XX:+UseConcMarkSweepGC -XX:NewRatio=12 程序通过了 170g 标记并且很高兴地进一步工作。