java配置OOM时保存堆转储文件

简介: java配置OOM时保存堆转储文件

当Java程序发生OOM(OutOfMemoryError)时,如果想要自动转储堆内存以便分析,可以在启动JVM时配置下列参数:

-XX:+HeapDumpOnOutOfMemoryError

这个参数可以让JVM在抛出OOM异常时自动生成heap dump文件。

-XX:HeapDumpPath=./java_pid<pid>.hprof

指定生成的heap dump文件的存放路径和文件名,这里使用了pid作为文件名的一部分,可以将不同时间的堆转储区分开。

-XX:OnOutOfMemoryError=<命令>

当OOM发生时,可以执行指定的命令,例如用于通知或执行脚本。

所以典型的带有堆转储的启动参数可以是:

java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./java_pid<pid>.hprof -Xmx512m ...

这样就可以在OOM发生时自动获取堆转储文件。分析这个文件可以定位内存泄漏或其他内存问题。

hprof文件自定义

一开始我想要使用生成时间作为heap dump文件名的一部分,配置方法如下:

-XX:HeapDumpPath=./java_oom-%t.hprof

经过实验,果然不行,原因是 HeapDumpPath 中如果使用 %t 或者 %%t 作为时间戳占位符,在运行时实际上并不能被 JVM 解析替换。

经过询问claude,得到两个解决方案,但是我还没实验,等验证过再来更新,先记录上

1.使用时间戳+计数器的方式生成唯一堆转储文件名

主要思路是:

  1. 启动Java程序时,使用一个循环脚本wrap着它
  2. 这个循环脚本中会不停地监听Java进程的PID
  3. 当检测到OOM产生时,脚本中会做两件事:
    3.1 动态设置HeapDumpPath参数,即堆转储文件的路径,文件名使用时间戳+计数器确保唯一性
    3.2 向Java进程发送kill -3 {pid} 信号,触发堆转储

这里的关键就是一旦监听到OOM事件,动态设置一个唯一的文件名,然后通知Java进程进行堆转储。

具体示例脚本代码:

# oom_wrap.sh
COUNT=1
while true; do
   PID=$(pgrep -f java) 
   if [ $? -ne 0 ]; then
     echo "Java process died"
     exit 1
   fi
   FILE=heapdump-${DATE}+${COUNT}.hprof  
   gsignal -s 3 -p heapdumpfile $FILE $PID 
   let COUNT=COUNT+1 
   sleep 10
done

启动Java程序时,用这个脚本包着:

./oom_wrap.sh java -Xmx128m ...

这里提到的gsignal是用来向进程发送信号的工具。

每次转储后复制文件到新的唯一文件名中

可以使用 Linux 的 crontab 定时任务来完成。

例如配置一个每小时执行的脚本:/path/to/heapdump-copy.sh

# heapdump-copy.sh
DUMP_DIR=/path/to/dumps
cd $DUMP_DIR
if [ -n "$(ls -1t java_oom_*.hprof | head -n 1)" ]; then
    NEWEST_DUMP=$(ls -1t java_oom_*.hprof | head -n 1)
    NEW_FILENAME=java_oom_$(date +%Y%m%d%H%M).hprof
    cp $NEWEST_DUMP $NEW_FILENAME
    echo "Copied new heap dump file $NEW_FILENAME"
fi

脚本逻辑:

  1. 检查 dumps 目录下最新的 java 堆转储文件
  2. 如果存在的话,复制到带时间戳的新文件名中

然后在 crontab 中增加定时任务:

0 * * * * /path/to/heapdump-copy.sh

这样就可以每小时检查并复制最新生成的 OOM 堆转储文件了。

crontab 定时任务还可以结合日志记录、监控报警使用,让自动化堆转储复制更加可靠。

目录
相关文章
|
2月前
|
Java
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
java小工具util系列5:java文件相关操作工具,包括读取服务器路径下文件,删除文件及子文件,删除文件夹等方法
84 9
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
93 2
|
9天前
|
人工智能 自然语言处理 Java
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
FastExcel 是一款基于 Java 的高性能 Excel 处理工具,专注于优化大规模数据处理,提供简洁易用的 API 和流式操作能力,支持从 EasyExcel 无缝迁移。
66 9
FastExcel:开源的 JAVA 解析 Excel 工具,集成 AI 通过自然语言处理 Excel 文件,完全兼容 EasyExcel
|
30天前
|
Java
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
java实现从HDFS上下载文件及文件夹的功能,以流形式输出,便于用户自定义保存任何路径下
88 34
|
1月前
|
存储 算法 Java
Java 内存管理与优化:掌控堆与栈,雕琢高效代码
Java内存管理与优化是提升程序性能的关键。掌握堆与栈的运作机制,学习如何有效管理内存资源,雕琢出更加高效的代码,是每个Java开发者必备的技能。
62 5
|
2月前
|
消息中间件 存储 Java
RocketMQ文件刷盘机制深度解析与Java模拟实现
【11月更文挑战第22天】在现代分布式系统中,消息队列(Message Queue, MQ)作为一种重要的中间件,扮演着连接不同服务、实现异步通信和消息解耦的关键角色。Apache RocketMQ作为一款高性能的分布式消息中间件,广泛应用于实时数据流处理、日志流处理等场景。为了保证消息的可靠性,RocketMQ引入了一种称为“刷盘”的机制,将消息从内存写入到磁盘中,确保消息持久化。本文将从底层原理、业务场景、概念、功能点等方面深入解析RocketMQ的文件刷盘机制,并使用Java模拟实现类似的功能。
46 3
|
2月前
|
Java 测试技术 Maven
Maven clean 提示文件 java.io.IOException
在使用Maven进行项目打包时,遇到了`Failed to delete`错误,尝试手动删除目标文件也失败,提示`java.io.IOException`。经过分析,发现问题是由于`sys-info.log`文件被其他进程占用。解决方法是关闭IDEA和相关Java进程,清理隐藏的Java进程后重新尝试Maven clean操作。最终问题得以解决。总结:遇到此类问题时,可以通过任务管理器清理相关进程或重启电脑来解决。
|
2月前
|
存储 缓存 安全
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见
在 Java 编程中,创建临时文件用于存储临时数据或进行临时操作非常常见。本文介绍了使用 `File.createTempFile` 方法和自定义创建临时文件的两种方式,详细探讨了它们的使用场景和注意事项,包括数据缓存、文件上传下载和日志记录等。强调了清理临时文件、确保文件名唯一性和合理设置文件权限的重要性。
160 2
|
2月前
|
存储 安全 Java
如何保证 Java 类文件的安全性?
Java类文件的安全性可以通过多种方式保障,如使用数字签名验证类文件的完整性和来源,利用安全管理器和安全策略限制类文件的权限,以及通过加密技术保护类文件在传输过程中的安全。
79 4
|
2月前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
99 4
下一篇
开通oss服务