进行堆转储会导致崩溃

问题描述

我有一个使用Kubernetes编排在容器内运行的Java进程。我在docker stats中发现内存占用过多。

我有-Xmx=40Gb,并且docker stats报告34.5 GiB内存。为了更好地了解堆使用情况,我尝试使用以下命令对正在运行的进程进行堆转储:

jmap -dump:live,format=b,file=/tmp/dump.hprof $pid

但这会导致容器重新启动。生成的转储文件大约为9.5 GiB,但是Eclipse Memory Analyzer报告该文件不完整,无法打开它。

Invalid HPROF file: Expected to read another 1,56,84,83,080 bytes,but only 52,82,104 bytes are available for heap dump record

在kubelet日志或容器日志中我没有找到太多信息,除了可能由堆转储引起的活动性探针故障?/

到目前为止,我无法重现该问题。我只是想了解可能发生的情况以及堆转储是否会干扰我的运行进程。我知道-dump:live标志会强制执行GC周期,然后收集堆转储,这可能会干扰我的运行进程吗?

解决方法

当JVM承受压力时,我曾遇到过类似情况。您可以附加此文件hs_err_pid日志吗?检查完该文件后,可以将操作系统配置为生成核心转储(以防系统尚未生成核心文件),并且应该能够从核心文件中获取堆转储。

在下面的link中,您可以阅读与JDK错误相关的类似问题。

此外,我建议您使用这些标志启用垃圾收集器日志文件和自动堆转储。启用gc.log后,请附加它,并在存储中分配足够的空间以保存堆转储。

XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M -Xloggc:/some/path/gc.log

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...