對最近linux下排查java內(nèi)存相關(guān)問題的命令做個(gè)小的總結(jié)
linux系列
top
top -p PID
pid為12415進(jìn)程的資源消耗情況眯搭。這里是以進(jìn)程為單位割去。
top -Hp PID
這里是以線程為單位。其中RES看到?jīng)]有線程占用的內(nèi)存都是3.3g,是因?yàn)镴VM內(nèi)存區(qū)域中大部分都是線程共享的类浪。
同時(shí)也可以通過shift+h在-p視圖下切換至線程視圖(set threads On),如下圖:
說明:top命令的TIME/TIME+是指的進(jìn)程/線程所使用的CPU時(shí)間肌似,不是進(jìn)程/線程啟動(dòng)到現(xiàn)在的時(shí)間费就,因此,如果一個(gè)進(jìn)程/線程使用的cpu很少川队,那即使這個(gè)進(jìn)程/線程已經(jīng)存在N長時(shí)間力细,TIME/TIME+也是很小的數(shù)值。
/proc/$pid/status
[#]$ cat /proc/12415/status
Name: java
State: S (sleeping)
Tgid: 12415
Pid: 12415
PPid: 1
TracerPid: 0
Uid: 502 502 502 502
Gid: 501 501 501 501
Utrace: 0
FDSize: 512
Groups: 501
VmPeak: 6734784 kB
VmSize: 6732236 kB
VmLck: 0 kB
VmHWM: 3476100 kB
VmRSS: 3473752 kB
VmData: 6560732 kB
VmStk: 88 kB
VmExe: 4 kB
VmLib: 17620 kB
VmPTE: 7404 kB
VmSwap: 0 kB
Threads: 108
SigQ: 0/23301
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000002
SigCgt: 2000000181005ccd
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: ffffffffffffffff
Cpus_allowed: f
Cpus_allowed_list: 0-3
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 1
nonvoluntary_ctxt_switches: 1
其中VmRSS表示就是占用的物理內(nèi)存固额。Threads表示當(dāng)前開啟的線程數(shù)眠蚂。
特別說明RSS【實(shí)際使用物理內(nèi)存】的含義:resident set size, the non-swapped physical memory that a task has used (in kiloBytes). (alias rssize, rsz).
pmap
[~]$ pmap -d 12415
12415: /usr/local/env/jdk1.8/bin/java -server -Xmx1024M -Xms1024M -Xmn512M -XX:MaxMetaspaceSize=128M -XX:MetaspaceSize=128M -XX:MaxDirectMemorySize=128M -XX:+UseConcMarkSweepGC -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses -XX:+CMSClassUnloadingEnabled -XX:+ParallelRefProcEnabled -XX:+CMSScavengeBeforeRemark -XX:-HeapDumpOnOutOfMemoryError -XX:+UseFastAccessorMethods -Xss256k -XX:SurvivorRatio=8 -XX:MaxTenuringThreshold=7 -XX:GCTimeRatio
Address Kbytes Mode Offset Device Mapping
0000000000400000 4 r-x-- 0000000000000000 0fc:00001 java
0000000000600000 4 rw--- 0000000000000000 0fc:00001 java
000000000116d000 996 rw--- 0000000000000000 000:00000 [ anon ]
00000000c0000000 1063680 rw--- 0000000000000000 000:00000 [ anon ]
0000000100ec0000 1033472 ----- 0000000000000000 000:00000 [ anon ]
0000003112e00000 88 r-x-- 0000000000000000 0fc:00001 libgcc_s-4.4.7-20120601.so.1
0000003112e16000 2044 ----- 0000000000016000 0fc:00001 libgcc_s-4.4.7-20120601.so.1
0000003113015000 4 rw--- 0000000000015000 0fc:00001 libgcc_s-4.4.7-20120601.so.1
00007f2c7d4a8000 12 r--s- 0000000000020000 0fc:00001 start.jar
00007f2c7d4ab000 4 rw--- 0000000000000000 000:00000 [ anon ]
00007f2c7d4ac000 4 r---- 0000000000000000 000:00000 [ anon ]
00007f2c7d4ad000 4 rw--- 0000000000000000 000:00000 [ anon ]
00007ffddeeed000 84 rw--- 0000000000000000 000:00000 [ stack ]
00007ffddef12000 4 r-x-- 0000000000000000 000:00000 [ anon ]
ffffffffff600000 4 r-x-- 0000000000000000 000:00000 [ anon ]
mapped: 6732236K writeable/private: 3786640K shared: 10820K
為方便展示省去中間部分內(nèi)容
這里看pmap重點(diǎn)是最后一行,進(jìn)程實(shí)際使用的物理內(nèi)存是writeable/private: 3786640K斗躏。
其他幾個(gè)點(diǎn)是什么意思呢逝慧?linux 會(huì)把一些shared libraries 載入到內(nèi)存中,在pmap 的輸出中瑟捣,這些shared libraries 的名字通常是 lib*.so 馋艺。如 libX11.so.6.2.0 。這個(gè) libX11.so.6.2.0 會(huì)被很多process load 到自己的運(yùn)行環(huán)境中迈套。上面展示的mapped的內(nèi)存就包含這部分和其他進(jìn)程共享的內(nèi)存【pmap is reporting virtual memory statistics which match top VIRT column . This is including data shared with other processes and other pages stored on disk.】捐祠。
google perf
gperftools是google開發(fā)的一款非常實(shí)用的工具集,主要包括:性能優(yōu)異的malloc free內(nèi)存分配器tcmalloc桑李;基于tcmalloc的堆內(nèi)存檢測和內(nèi)存泄漏分析工具h(yuǎn)eap-profiler,heap-checker踱蛀;基于tcmalloc實(shí)現(xiàn)的程序CPU性能監(jiān)測工具cpu-profiler窿给。可以對CPU時(shí)間片率拒、內(nèi)存等系統(tǒng)資源的分配合使用進(jìn)行分析崩泡。使用perf對一個(gè)程序分析一般分為下面幾個(gè)步驟:
- 加入對google-perftools庫的依賴
- 運(yùn)行目標(biāo)程序,并用某種方式啟動(dòng)/終止剖析函數(shù)并產(chǎn)生剖析結(jié)果
- 運(yùn)行剖析結(jié)果轉(zhuǎn)換工具猬膨,江不可讀的結(jié)果轉(zhuǎn)化成某種格式的文檔(pdf,txt,image等)
原理:該工具主要利用了unix的一個(gè)環(huán)境變量LD_PRELOAD角撞,它允許你要加載的動(dòng)態(tài)庫優(yōu)先加載起來,相當(dāng)于一個(gè)Hook勃痴,于是可以針對同一個(gè)函數(shù)可以選擇不同的動(dòng)態(tài)庫里的實(shí)現(xiàn)了谒所,比如googleperftools就是將malloc方法替換成了tcmalloc的實(shí)現(xiàn),這樣就可以跟蹤內(nèi)存分配路徑了沛申×恿欤可以理解為在分配內(nèi)存的同時(shí)增加內(nèi)存分配跟蹤的功能。
下面簡單說下針對JVM的分析過程:
- 在JVM參數(shù)中增加下面的配置:
export LD_PRELOAD=/usr/lib64/libtcmalloc.so
export HEAPPROFILE=/home/lg/temp
export HEAP_PROFILE_ALLOCATION_INTERVAL= 1073741824
LD_PRELOAD
perftools一切都是以tcmalloc為基礎(chǔ)铁材。這里指定tcmalloc的安裝位置尖淘;
HEAPPROFILE
指定heap profile存放的位置
HEAP_PROFILE_ALLOCATION_INTERVAL
每當(dāng)一定量的內(nèi)存被新申請分配出來時(shí),就會(huì)輸出profile文件著觉,這個(gè)變量值就是控制多少字節(jié)村生。默認(rèn)值是102410241024byte【1G】。一般情況下會(huì)調(diào)小一些饼丘。
- 運(yùn)行程序輸出heap文件
在jvm中加入上面的參數(shù)后梆造,啟動(dòng)程序。這時(shí)候日志中會(huì)顯示類似下面的內(nèi)容:
Dumping heap profile to /home/lg/temp/_10030.0001.heap (1755151 MB allocated cumulatively, 1267 MB currently in use)
顯示累計(jì)的對外內(nèi)存的分配和當(dāng)前使用的對外內(nèi)存的大小葬毫。同時(shí)配置的對應(yīng)的目錄中會(huì)產(chǎn)生.heap文件。接下來的工作就是分析這些文件屡穗。
- 通過命令行分析文件
命令:
pprof --text /usr/local/env/jdk1.8/bin/java _10030.0001.heap
輸出結(jié)果:
Using local file /usr/local/env/jdk1.8/bin/java.
Using local file _10030.0001.heap.
Total: 0.1 MB
0.0 83.9% 83.9% 0.1 99.9% __FRAME_END__
0.0 6.1% 90.0% 0.0 6.1% read_alias_file
0.0 5.6% 95.6% 0.0 5.6% _nl_intern_locale_data
0.0 3.1% 98.6% 0.0 3.1% _nl_make_l10nflist
0.0 0.7% 99.3% 0.0 0.7% __gconv_lookup_cache
0.0 0.3% 99.6% 0.0 0.3% strdup
0.0 0.2% 99.8% 0.0 5.8% _nl_load_locale_from_archive
0.0 0.1% 99.9% 0.0 0.7% __wcsmbs_load_conv
0.0 0.1% 99.9% 0.0 0.1% std::basic_string::_Rep::_S_create
0.0 0.0% 100.0% 0.0 0.0% set_binding_values
0.0 0.0% 100.0% 0.0 0.0% new_composite_name
0.0 0.0% 100.0% 0.0 0.0% 00007f5e3a5f3de1
0.0 0.0% 100.0% 0.0 0.1% 00007f5e3a5f3dc0
0.0 0.0% 100.0% 0.0 0.1% 00007f5e3a602405
0.0 0.0% 100.0% 0.0 0.1% 0x00007ffc250bc6e0
0.0 0.0% 100.0% 0.0 0.1% 0x2f6c61636f6c2f71
0.0 0.0% 100.0% 0.0 9.2% __dcigettext
0.0 0.0% 100.0% 0.0 0.7% __gconv_find_transform
0.0 0.0% 100.0% 0.1 89.5% __libc_start_main
0.0 0.0% 100.0% 0.0 0.1% _init
0.0 0.0% 100.0% 0.0 0.1% _init (inline)
0.0 0.0% 100.0% 0.0 6.1% _nl_expand_alias
0.0 0.0% 100.0% 0.0 9.2% _nl_find_domain
0.0 0.0% 100.0% 0.0 5.8% _nl_find_locale
0.0 0.0% 100.0% 0.0 0.0% bindtextdomain
0.0 0.0% 100.0% 0.0 0.7% mblen
0.0 0.0% 100.0% 0.0 0.7% mbrtowc
0.0 0.0% 100.0% 0.0 6.1% setlocale
0.0 0.0% 100.0% 0.0 0.1% std::basic_string::basic_string
0.0 0.0% 100.0% 0.0 0.1% std::basic_string::copy
0.0 0.0% 100.0% 0.0 7.6% strerror
0.0 0.0% 100.0% 0.0 7.6% strerror_r
0.0 0.0% 100.0% 0.0 0.0% textdomain
以上不是實(shí)際問題的數(shù)據(jù)
結(jié)果代表的含義:
- c1 Number of profiling samples in this function(函數(shù)分析樣本數(shù)量)
- c2 Percentage of profiling samples in this function(函數(shù)分析樣本的百分比)
- c3 Percentage of profiling samples in the functions printed so far(
到目前為止打印的函數(shù)中的分析樣本的百分比) - c4 Number of profiling samples in this function and its callees(
此函數(shù)及其被調(diào)用者的性能分析樣本數(shù)) - c5 Percentage of profiling samples in this function and its callees(此函數(shù)及其被調(diào)用者的性能分析樣本的百分比)
- c5 Function name
通過perftools可以定位可能引起問題的函數(shù)或者有嫌疑的內(nèi)存地址贴捡。針對JVM進(jìn)程可能需要進(jìn)一步借用其他工具來分析。
參考鏈接:
heap_checker
perftoos使用心得
下一篇再介紹JVM相關(guān)的工具村砂。