关于linux下内存问题排查的工具

对最近linux下排查java内存相关问题的命令做个小的总结

linux系列

top

top -p PID
pid为12415进程的资源消耗情况。这里是以进程为单位。

top -Hp PID


这里是以线程为单位。其中RES看到没有线程占用的内存都是3.3g,是因为JVM内存区域中大部分都是线程共享的。
同时也可以通过shift+h在-p视图下切换至线程视图(set threads On),如下图:

说明:top命令的TIME/TIME+是指的进程/线程所使用的CPU时间,不是进程/线程启动到现在的时间,因此,如果一个进程/线程使用的cpu很少,那即使这个进程/线程已经存在N长时间,TIME/TIME+也是很小的数值。

/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表示就是占用的物理内存。Threads表示当前开启的线程数。

特别说明RSS【实际使用物理内存】的含义: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

为方便展示省去中间部分内容

这里看pmap重点是最后一行,进程实际使用的物理内存是writeable/private: 3786640K。
其他几个点是什么意思呢?linux 会把一些shared libraries 载入到内存中,在pmap 的输出中,这些shared libraries 的名字通常是 lib*.so 。如 libX11.so.6.2.0 。这个 libX11.so.6.2.0 会被很多process load 到自己的运行环境中。上面展示的mapped的内存就包含这部分和其他进程共享的内存【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开发的一款非常实用的工具集,主要包括:性能优异的malloc free内存分配器tcmalloc;基于tcmalloc的堆内存检测和内存泄漏分析工具heap-profiler,heap-checker;基于tcmalloc实现的程序CPU性能监测工具cpu-profiler。可以对CPU时间片、内存等系统资源的分配合使用进行分析。使用perf对一个程序分析一般分为下面几个步骤:

  1. 加入对google-perftools库的依赖
  2. 运行目标程序,并用某种方式启动/终止剖析函数并产生剖析结果
  3. 运行剖析结果转换工具,江不可读的结果转化成某种格式的文档(pdf,txt,image等)

原理:该工具主要利用了unix的一个环境变量LD_PRELOAD,它允许你要加载的动态库优先加载起来,相当于一个Hook,于是可以针对同一个函数可以选择不同的动态库里的实现了,比如googleperftools就是将malloc方法替换成了tcmalloc的实现,这样就可以跟踪内存分配路径了。可以理解为在分配内存的同时增加内存分配跟踪的功能。

下面简单说下针对JVM的分析过程:

  1. 在JVM参数中增加下面的配置:
export LD_PRELOAD=/usr/lib64/libtcmalloc.so
export HEAPPROFILE=/home/lg/temp
export HEAP_PROFILE_ALLOCATION_INTERVAL= 1073741824

LD_PRELOAD
perftools一切都是以tcmalloc为基础。这里指定tcmalloc的安装位置;
HEAPPROFILE
指定heap profile存放的位置
HEAP_PROFILE_ALLOCATION_INTERVAL
每当一定量的内存被新申请分配出来时,就会输出profile文件,这个变量值就是控制多少字节。默认值是102410241024byte【1G】。一般情况下会调小一些。

  1. 运行程序输出heap文件
    在jvm中加入上面的参数后,启动程序。这时候日志中会显示类似下面的内容:
Dumping heap profile to /home/lg/temp/_10030.0001.heap (1755151 MB allocated cumulatively, 1267 MB currently in use)

显示累计的对外内存的分配和当前使用的对外内存的大小。同时配置的对应的目录中会产生.heap文件。接下来的工作就是分析这些文件。

  1. 通过命令行分析文件
    命令:
pprof --text /usr/local/env/jdk1.8/bin/java _10030.0001.heap

输出结果:

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

以上不是实际问题的数据

结果代表的含义:

  • c1 Number of profiling samples in this function(函数分析样本数量)
  • c2 Percentage of profiling samples in this function(函数分析样本的百分比)
  • c3 Percentage of profiling samples in the functions printed so far(
    到目前为止打印的函数中的分析样本的百分比)
  • c4 Number of profiling samples in this function and its callees(
    此函数及其被调用者的性能分析样本数)
  • c5 Percentage of profiling samples in this function and its callees(此函数及其被调用者的性能分析样本的百分比)
  • c5 Function name

通过perftools可以定位可能引起问题的函数或者有嫌疑的内存地址。针对JVM进程可能需要进一步借用其他工具来分析。

参考链接:
heap_checker
perftoos使用心得

下一篇再介绍JVM相关的工具。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容