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
查看報告