快速堆转储但内存不足
fast heap dumps but on out of memory
我们都知道很好的旧标志 +HeapDumpOnOutOfMemoryError
,用于在 JVM 运行 内存不足时进行堆转储。问题是对于大堆,这需要越来越多的时间。
有一种方法可以使用 GNU 调试器进行快速堆转储...
您有效地获取了进程的核心文件(非常快),然后使用 jmap
将其转换为堆转储格式...这是工作中最慢的部分。
然而,这仅在您手动执行时才会发生,当您的 java 应用程序 运行 在容器中时,通常会有一个固定的超时时间,直到您的应用程序被非正常地杀死...对于 kube i相信默认是30秒。
出于多种原因,我不想将此超时延长到更大的数字。有没有办法在 java 运行s 内存不足时仅触发核心文件转储?或者我们只是受限于 +HeapDumpOnOutOfMemoryError
flag 提供的任何东西?
我可以想到 2 种可能的解决方案,但它不仅适用于内存不足的情况,而且也会崩溃:
您可以使用 java 的 -XX:OnError
选项 运行 您自己的脚本或 gcore,(gdb) generate-core-file(取决于您的OS) 创建核心转储,稍后您可以使用调试器(如 gdb)附加到它。
您可以按照它提供的方式在 OS 中启用自动核心转储。 对于 Redhat:
要启用:将文件 /etc/systemd/system.conf 中的相关行编辑为 DefaultLimitCORE=infinity
重新启动并通过 ulimit -c unlimited
移除核心转储的限制。
当您的应用程序崩溃时,必须在其工作目录中创建 dumb。
我们都知道很好的旧标志 +HeapDumpOnOutOfMemoryError
,用于在 JVM 运行 内存不足时进行堆转储。问题是对于大堆,这需要越来越多的时间。
有一种方法可以使用 GNU 调试器进行快速堆转储...
您有效地获取了进程的核心文件(非常快),然后使用 jmap
将其转换为堆转储格式...这是工作中最慢的部分。
然而,这仅在您手动执行时才会发生,当您的 java 应用程序 运行 在容器中时,通常会有一个固定的超时时间,直到您的应用程序被非正常地杀死...对于 kube i相信默认是30秒。
出于多种原因,我不想将此超时延长到更大的数字。有没有办法在 java 运行s 内存不足时仅触发核心文件转储?或者我们只是受限于 +HeapDumpOnOutOfMemoryError
flag 提供的任何东西?
我可以想到 2 种可能的解决方案,但它不仅适用于内存不足的情况,而且也会崩溃:
您可以使用 java 的
-XX:OnError
选项 运行 您自己的脚本或 gcore,(gdb) generate-core-file(取决于您的OS) 创建核心转储,稍后您可以使用调试器(如 gdb)附加到它。您可以按照它提供的方式在 OS 中启用自动核心转储。 对于 Redhat:
要启用:将文件 /etc/systemd/system.conf 中的相关行编辑为 DefaultLimitCORE=infinity
重新启动并通过 ulimit -c unlimited
移除核心转储的限制。
当您的应用程序崩溃时,必须在其工作目录中创建 dumb。