[转帖]jmap执行失败了,怎么获取heapdump?
https://www.jianshu.com/p/f4bfd169b4ca

在之前的OOM问题复盘中,我们添加了jmap脚本来自动dump内存现场,方便排查OOM问题。
但当我反复模拟OOM场景测试时,发现jmap有时可以dump成功,有时会报错,如下:

经过网上一顿搜索,发现两种原因可能导致这个问题,一是执行jmap用户与jvm进程用户不一致,二是/tmp/.java_pidXXX文件被删除,但经过检查,这都不是我们jmap失败的原因。
经过了解,jmap导出内存的原理,大致如下:

- 如果jvm进程id是8255,jmap会先创建一个
/tmp/.java_pid8255文件,然后发送SIGQUIT信号给jvm。 - jvm收到信号后启动AttachListener线程,以UNIX domain socket的形式监听
/tmp/.java_pid8255文件,以接收命令。 - jmap也以UNIX domain socket的形式连接上
/tmp/.java_pid8255文件,并发送dumpheap命令给jvm,这个过程中jvm会检查命令发送方用户的euid/egid是否与自己一致。 - AttachListener线程收到dumpheap命令后,等到JVM进入Safepoint后,执行HeapDumper操作以导出heap.hprof文件。
可以看出,当jvm已经卡死,或有长时间的GC正在Safepoint中执行,都会导致jmap长时间读不到命令的响应而超时失败!
使用jmap -F
当给jmap添加-F参数时,jmap会使用Linux的ptrace机制来导出堆内存,ptrace是Linux平台的一种调试机制,像strace、gdb都是基于它开发的,它使得调试进程(jmap)可以直接读取被调试进程(jvm)的原生内存,然后jmap再根据jvm的内存布局规范,将原生内存转换为hprof格式。
但在实际执行时,会发现jmap -F执行得非常慢,可能要几个小时,这是因为ptrace每次只能读一个字的内存,而我们的堆有10G,因此jmap -F对于我们几乎无法使用。
注:这里说的原生程序,指的是类似于C/C++这种直接编译出来、不需要依赖语言虚拟机的程序,而原生内存,指的是通过malloc或mmap等直接申请出来的内存。
使用gcore
有过Linux下原生程序调试经验的,应该会知道gcore这个实用工具,它可用来生成程序原生内存的core文件,然后jstack、jmap等都可以读取此类文件,如下:
# 生成core文件,8787是进程号
$ gcore -o core 8787
Saved corefile core.8787
[Inferior 1 (process 8787) detached]
$ ll -lh core.8787
-rw-r--r-- 1 work work 5.8G 2023-04-16 11:40:00 core.8787
# 从core文件中读取线程栈
$ jstack `which java` core.8787
# 将core文件转换为hprof文件,很慢,建议摘流量后执行
$ jmap -dump:format=b,file=heap.hprof `which java` core.8787
但是当我使用jmap转换core文件时,我发现我本机测试时可以成功,但在测试服务器上却一直报错,如下:

我网上找了好久,都没找到报此错误的原因...
但我发现gcore执行时,是有一些警告信息的,如下:

看起来可能是gcore导出的core文件不全,联想到jvm部署在容器中,怀疑是有某些权限限制,导致部分程序内存导出失败了。
使用Linux内核的coredump机制
除了gcore可以导原生内存,其实Linux内核也有自动的coredump机制,即进程在收到某些信号后,会自动触发内核的coredump机制,内核会负责将进程的原生内存保存为core文件,而内核一般是最高权限运行的,所以它生成的core文件应该是完整的。
先开启coredump机制,如下:
# 检查是否开启,输出unlimited表示core文件不受限制,即完全开启
$ ulimit -c
# 临时开启coredump
$ ulimit -c unlimited
# 永久开启
$ echo "ulimit -c unlimited" >> /etc/profile
然后,配置一下coredump文件保存位置,如下:
# 查看当前配置
$ cat /proc/sys/kernel/core_pattern
/home/core/core.%e.%p.%t
# 配置coredump文件保存位置,并使其生效
$ vi /etc/sysctl.conf
kernel.core_pattern=/home/core/core.%e.%p.%t
$ sysctl –p /etc/sysctl.conf
core_pattern占位符解释
| 占位符 | 解释 |
|---|---|
| %p | pid |
| %u | uid |
| %g | gid |
| %s | signal number |
| %t | UNIX time of dump |
| %h | hostname |
| %e | executable filename |
注:如果没有权限修改core_pattern路径,可考虑使用软链接
ln -s做路径跳转,当然,还需要保证coredump路径有写入权限。
配置ok后,可通过kill发送信号来触发内核coredump,可触发coredump的常见信号如下:
- SIGQUIT 数值2 从键盘输入
Ctrl+'\'可以产生此信号 - SIGILL 数值4 非法指令
- SIGABRT 数值6 abort调用
- SIGSEGV 数值11 非法内存访问
- SIGTRAP 数值5 调试程序时使用的断点
我选择了SIGABRT信号,即kill -6,经过验证,可生成core文件,而且core文件也能被jmap转换为hprof文件。
有了hprof文件,就可以愉快地使用MAT、JVisualVM、JMC等工具进行内存分析啦
[转帖]jmap执行失败了,怎么获取heapdump?的更多相关文章
- jmap执行失败了,怎么获取heapdump?
原创:扣钉日记(微信公众号ID:codelogs),欢迎分享,非公众号转载保留此声明. 在之前的OOM问题复盘中,我们添加了jmap脚本来自动dump内存现场,方便排查OOM问题. 但当我反复模拟OO ...
- SQL Server2005作业执行失败的解决办法
数据库:SQL Server 2005,运行环境:Windows Server 2008 在数据库里的所有作业都执行失败,包括自动执行和手动执行.在事件查看器里看到的错误报告如下: 该作业失败. ...
- JAVA中执行JavaScript代码并获取返回值
JAVA中执行JavaScript代码并获取返回值 场景描述 实现思路 技术要点 代码实现 测试方法 运行结果 改进空间 场景描述 今天在CSDN上偶然看到一个帖子对于一段字符串 “var p=‘xx ...
- SQL Server2005/2008 作业执行失败的解决办法
数据库:SQL Server 2005/2008,运行环境:Windows Server 2008 在数据库里的所有作业都执行失败,包括自动执行和手动执行.在事件查看器里看到的错误报告如下: 该 作 ...
- 章节十七章、2- 给执行失败的case截图
一.案例演示 1.首先我们把截图的方法单独进行封装方便以后调用. package utilities; import java.io.File; import java.io.IOException; ...
- etcd定时任务脚本执行失败
etcd定时任务脚本执行失败 报错如下:etcdctl命令不存在 是因为在脚本中etcdctl命令没有写绝对路径,修改标记部分改成绝对路径 可以先获取路径然后改成绝对路径问题解决 which etcd ...
- vs2015 生成项目时,提示执行失败,参数错误
今天vs2015 生成项目时,提示执行失败,参数错误.查了很多资料未解决 后来,发现只有一个项目出现这个问题,其他项目生成正常.怀疑是该项目解决方案的问题 于是将解决项目中的项目移除,逐一生成引用,解 ...
- 存储过程执行失败与sql668n
某日监控报存储过程执行失败,查看返回码为sql668n [db2inst1@limt bin]$ db2 ? sql668n SQL0668N Operation not allowed for re ...
- 【转】mysql触发器的实战(触发器执行失败,sql会回滚吗)
1 引言Mysql的触发器和存储过程一样,都是嵌入到mysql的一段程序.触发器是mysql5新增的功能,目前线上凤巢系统.北斗系统以及哥伦布系统使用的数据库均是mysql5.0.45版本,很多程 ...
- Oracle 11g RAC 第二节点root.sh执行失败后再次执行root.sh
Oracle 11g RAC 第二节点root.sh执行失败后再次执行root.sh前,要先清除之前的crs配置信息 # /u01/app/11.2.0/grid/crs/install/rootcr ...
随机推荐
- flutter中显示年月日、星期与时间
代码 import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'dart:async'; imp ...
- 一文带你掌握Redis操作指南
摘要:Redis是一种支持Key-Value等多种数据结构的存储系统. Redis是一种支持Key-Value等多种数据结构的存储系统.可用于缓存,事件发布或订阅,高速队列等场景.该数据库使用ANSI ...
- vue2升级vue3: h、createVNode、render、createApp使用
h.createVNode 杂乱笔记,凑合着看,不喜勿喷! h 函数是什么 h 函数本质就是 createElement() 的简写,作用是根据配置创建对应的虚拟节点,在vue 中占有极其重要的地位! ...
- 泛互联网行业A/B测试全解析:产品优化的创新之道
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 近期,火山引擎数智平台举办了"超话数据:企业产品优化分享"的活动.火山引擎产品解决方案专 ...
- 中企出海,用火山引擎DataTester开启增长第一步
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 今年 Google 宣布其提供的A/B测试工具 Optimize 将在2023年9月30号停止服务.在全球化浪 ...
- 火山引擎 DataTester:构建增长闭环,3-5 人即可搭建企业增长团队
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 增长是一个老生常谈的话题,对许多企业而言这个词都很熟悉,但在实践过程中仍然有很多的疑问,比如指标体系应该怎么搭建? ...
- 大数据-业务数据采集-FlinkCDC 读取 MySQL 数据存入 Kafka
目录 作用 app 产生各层数据的 flink 任务 bean 数据对象 common 公共常量 utils 工具类 app.ods.FlinkCDC.java package com.atguigu ...
- Xml Entity 实体互转(XStream)
http://x-stream.github.io/tutorial.html 项目中用了 JAXB 方式 Xml Entity 实体互转(JAXB) 实体: import com.thoughtwo ...
- k8s--容器挂载 error: /proc must be mounted
问题描述: 登录容器,执行ps命令查看进程时,报错/proc挂载问题,如下图,按照图上所说在/etc/fstab 下添加,还是报错 思路: 可能是lxcfs挂了或者hang住了,具体要登录k8s节点实 ...
- MAVEN 配置和基本使用
Maven 安装配置 解压 apache-maven-3.6.1.rar 既安装完成 配置环境变量 MAVEN_HOME 为安装路径的 bin 目录 在 Path 下添加 %MAVEN_HOME%\b ...