gpt4 book ai didi

java - 内存不足错误 : Java heap size when memory is available

转载 作者:IT王子 更新时间:2023-10-28 23:34:16 26 4
gpt4 key购买 nike

我正在使用 java -Xmx240g mypackage.myClass 运行 java

操作系统是 Ubuntu 12.10。

top 表示 MiB Mem 245743 total,并显示 java 进程从一开始就有 virt 254g,并且 res 稳步增加到 169g。那时看起来它开始垃圾收集很多,我认为是因为该程序是单线程的,并且 CPU% 大部分是 100% 最多此时,它在1300-2000左右跳跃(我断定它是多线程垃圾收集器),然后res慢慢移动到172g。那时java崩溃了

线程“main”java.lang.OutOfMemoryError 中的异常:Java 堆空间

new double[2000][5]

的行

java -version

java 版本“1.7.0_15”
OpenJDK 运行环境 (IcedTea7 2.3.7) (7u15-2.3.7-0ubuntu1~12.10)
OpenJDK 64-Bit Server VM(build 23.7-b01,混合模式)

硬件为 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 标记并且很高兴地进一步工作。

最佳答案

分析

您需要做的第一件事是获取堆转储,这样您就可以准确地计算出 JVM 崩溃时堆的样子。将这组标志添加到命令行:

-XX:+HeapDumpOnOutOfMemoryError -verbose:gc -XX:+PrintGCDetails

当发生崩溃时,JVM 会将堆写入磁盘。坦率地说,在这么大的堆上需要很长时间。下载 Eclipse MAT或者如果您已经在运行 Eclipse,请安装该插件。从那里,您可以加载堆转储并运行几个 jar 头报告。您需要检查 Leak Suspects 和 Dominator Tree 以查看您的内存去向并确定您没有实际的泄漏。

在那之后,我会推荐你​​read this document Oracle 关于垃圾收集的文章,但是您可以考虑以下几点:

并发 GC

-XX:+UseConcMarkSweepGC 

我从未听说有人在这么大的堆上使用仅并行收集器而侥幸成功。您可以激活并发收集器,并且您需要阅读增量模式并确定它是否适合您的工作负载/硬件组合。

无堆率

-XX:MinHeapFreeRatio=25

当您进行完整收集时,将其调低以降低垃圾收集器的阈值。这可能会阻止您在执行完整收集时耗尽内存。 40% 是默认值,请尝试使用较小的值。

新比率

-XX:NewRatio

我们需要了解更多关于您的实际工作量的信息:这是一个网络应用吗?一个 Swing 应用程序?取决于对象在堆上保持 Activity 的时间长短,将对新的比率值产生影响。默认情况下,像您正在运行的服务器模式 VM 具有相当高的新比率 (8:1),如果您有很多长生命周期对象,这可能不适合您。

关于java - 内存不足错误 : Java heap size when memory is available,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16095439/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com