文章目录
1. pmap 命令
pmap
命令可以查看进程的内存映像信息,其输出内容来自于/proc/<pid>/maps
和/proc/<pid>/smaps
这两个文件,maps
文件包含了每一段内存的大概描述,smaps
里包含了具体每段的详细信息
1.1 使用方式
在 Linux 系统中使用man pmap
可查看其帮助文档,这个命令的格式为 pmap [options] pid
,其中 options 选项如下表:
Options | 功能 |
---|---|
-x, –extended | 显示扩展格式 |
-d, –device | 显示设备格式 |
-q, –quiet | 不显示头尾行 |
-A, –range low,high | 显示给定地址范围的结果,参数以逗号分隔 |
-X | 显示比 -x 选项更详细的信息, 信息来自文件 /proc/PID/smaps |
-XX | 显示 kernel能提供的一切信息 |
-c, –read-rc | 读取默认配置 |
-V, –version | 显示版本信息 |
1.2 示例
pmap -x 7642
命令打印进程 7642 的内存信息,其中 扩展格式和设备格式字段含义如下
字段 | 含义 |
---|---|
Address | 映像起始地址 |
Kbytes | 映像大小 |
RSS | 驻留集大小 |
Dirty | 脏页大小 |
Mode | 映像权限 |
Mapping | 映像支持文件,[anon]为已分配内存[stack]为程序堆栈 |
Offset | 文件偏移 |
Device | 设备名 |
// 进程启动命令
7642: java -Xmx256m -server -XX:+PrintGCApplicationStoppedTime -jar bin/center.jar
Address Kbytes RSS Dirty Mode Mapping
0000000000400000 4 0 0 r-x-- java
0000000000600000 4 4 4 rw--- java
00000000018dc000 1208 1092 1092 rw--- [ anon ]
00000000f0000000 257536 134672 134672 rw--- [ anon ]
00000000ffb80000 4608 0 0 ----- [ anon ]
0000000100000000 12080 12052 12052 rw--- [ anon ]
0000000100bcc000 1036496 0 0 ----- [ anon ]
00007f53dda8d000 256 60 60 rw--- [ anon ]
......
2. gdb 调试工具
使用 gdb
工具可以 dump 指定地址范围的内存,该操作会影响服务,需注意dump的内存块大小,慎用。以下命令的含义是dump 指定进程 13618 起始地址为0x7ffc0508b000,结束地址为 0x7ffc0508b000 加上偏移量 132000 的内存,并将其保存到 199.dump 文件中
gdb --batch --pid 13618 -ex "dump memory 199.dump 0x7ffc0508b000 0x7ffc0508b000+132000"
内存起始地址可以使用 pmap
命令查看,Address
字段即为内存地址,但是要注意需要将地址高位的 0 换成0x
开头,比如 dump 以上 0000000000400000 开始,0000000000600000 结束的内存
,需要转化成 0x400000 0x600000
或者使用偏移量方式 0x400000 0x400000+4000
dump 出来的文件其实是二进制形式的,直接查看就是一堆乱码,可以使用 strings -n 10 199.dump
查看 10 个字符以上的内存内容
- 其实即便到这一步也很难看出来有用的信息,后续可以借助
perf
工具继续排查。使用perf record -g -p <pid>
开启监控栈函数调用,运行一段时间后 Ctrl+C 结束,会生成一个文件perf.data,执行perf report -i perf.data
查看报告