欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 教育 > 培训 > 记录一次OOM查找原因的过程

记录一次OOM查找原因的过程

2024/10/24 9:19:08 来源:https://blog.csdn.net/qq_28194001/article/details/139757480  浏览:    关键词:记录一次OOM查找原因的过程

背景

在一次上班时,用户反馈系统卡了,后台监控发现内存溢出了,频繁地触发了FullGC,但是内存却一直没有降下来。
而由于每次遇上这种问题时都是急急忙忙,需要尽快恢复服务供用户使用,所以排查的机会也不多,这次记录下之前收藏的排查方法,便于后续使用。

操作步骤

概览(只是忘记步骤看此处即可)

  1. 执行jpsps命令 查看当前服务器中运行的java应用进程号
  2. jstack 进程号 > 指定文件名生成线程快照(相比于jmap对系统性能影响较小)
  3. top -Hp 进程号查看进程中的线程状态,记录/截图该进程中占用资源最多的前几个线程号
  4. printf "%x\n" 线程号命令将上一步获取到的线程号转为十六进制
  5. 在快照文件中根据十六进制线程号查找堆栈快照信息

详细步骤演示及说明

一、找到执行的java应用

  1. 执行jps或者ps命令,查看当前服务器中运行的java应用进程号
  • jps属于jdk的命令,简短地展示正在运行的java应用
    使用jps找到正在运行的java应用
  • ps属于Linux的命令,会展示详细的vm参数信息(如有多个java应用可根据应用路径找到自己的服务)
    使用ps命令显示正在运行的应用详情

二、生成线程堆栈快照

jstack 进程号 > 指定文件名

该命令对系统性能影响较小,不会像jmap造成系统STW(Stop The World)而无法运行,可以隔几秒或1分钟生成多几份

  • ./jstack 6166 > /data/appsvr/rookie/stack1.out
    jstack命令生成快照文件

三、查看进程中的线程状态,找到嫌疑线程

执行top -Hp 进程号查看进程中的线程状态,记录占用资源最多的前几个线程号,因为数据会动态变化,建议截几张图保存,用于后面转换十六进制在快照文件中查询
使用top命令记录下嫌疑线程

四、转换嫌疑线程为十六进制

printf "%x\n" 线程号命令将上一步获取到的线程号转为十六进制,用于在快照信息中进行查找,因为快照信息中记录的线程ID为十六进制
转换十六进制

五、在快照文件中查找调用栈信息

  1. Linux中使用less命令或者将文件拉下来根据转换的十六进制线程号查找栈信息
  2. 有时候占用CPU资源最多的线程号不一定是有用的信息,像我使用1820查找的内容就没有多少有效信息,反而使用19b7找到了执行的java代码
    1820线程的快照信息
    19b7的快照信息

反思

  • 当时出现问题时定位到了是数据导出的问题影响的,而对于文件导出逻辑,系统应该有导出日志供运维查看,而不必从后台查找,例如导出参数,报表名称,数据量,操作用户,开始时间等等
  • 还有一个目前未明白的是top命令监控的线程号和快照中实际运行的对应不上,看了程序没有启用多线程去处理导出,除了是生成快照时的处理线程跟监控时间差的问题外,还有其他原因导致吗?有大佬了解的话可以留下评论帮忙解答下

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com