对于内存问题排查,或者OOM问题排查,一般会涉及到如下文件,下面将如下文件的分析和设置介绍一下,这也是本文档的重点,后面排查内存信息还是要根据这些文件信息来排查。其实未必是有内存泄露,也可能是一些策略有问题,比如线程数目的增加,buffer的申请、释放时间交集等。
min_free_kbytes用来确定系统开始回收内存的阀值,控制系统的空闲内存。值越高,内核越早开始回收内存,空闲内存越高。
可以使用如下方式:echo 65535 > /proc/sys/vm/min_free_kbytes将系统保留内存设置为6M。
清系统缓存:
#echo 1 > /proc/sys/vm/drop_caches 清理页缓存
#echo 2 > /proc/sys/vm/drop_caches 清理文件缓存
#echo 3 > /proc/sys/vm/drop_caches 清理也缓存和文件缓存
当一个sysrq命令被触发,内核将会打印信息到内核的环形缓冲并输出到系统控制台。此信息一般也会通过syslog输出到/var/log/messages.
有时候,可能系统已经无法响应,syslogd可能无法记录此信息。在这种情况下,建议您配置一个串口终端来收集这个信息。
#echo m > /proc/sysrq-trigger 导出内存分配信息
#echo t > /proc/sysrq-trigger 导出线程状态信息
#echo p > /proc/sysrq-trigger 导出当前CPU寄存器信息和标志位的信息
#echo w > /proc/sysrq-trigger将进入uninterrupted状态的任务的信息dump出来
root@ubuntu:/home/linux# echo m >/proc/sysrq-trigger
root@ubuntu:/home/linux# dmesg -c
SysRq : Show Memory
Mem-Info:
DMA per-cpu:
CPU 0: hi: 0, btch: 1 usd: 0
CPU 1: hi: 0, btch: 1 usd: 0
Normal per-cpu:
CPU 0: hi: 186, btch: 31 usd: 93
CPU 1: hi: 186, btch: 31 usd: 140
HighMem per-cpu:
CPU 0: hi: 186, btch: 31 usd: 185
CPU 1: hi: 186, btch: 31 usd: 13
active_anon:22129 inactive_anon:645isolated_anon:0
active_file:52387 inactive_file:81072isolated_file:0
unevictable:0 dirty:6 writeback:0unstable:0
free:336695 slab_reclaimable:12052slab_unreclaimable:2825
mapped:11208 shmem:892 pagetables:795bounce:0
free_cma:0
DMA free:15900kB min:788kB low:984kBhigh:1180kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kBunevictable:0kB isolated(anon):0kB isolated(file):0kB present:15992kBmanaged:15916kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kBslab_reclaimable:0kB slab_unreclaimable:16kB kernel_stack:0kB pagetables:0kBunstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0all_unreclaimable? no
lowmem_reserve[]: 0 843 1999 1999
Normal free:635940kB min:42908kBlow:53632kB high:64360kB active_anon:0kB inactive_anon:0kB active_file:75608kBinactive_file:85104kB unevictable:0kB isolated(anon):0kB isolated(file):0kBpresent:897016kB managed:864652kB mlocked:0kB dirty:24kB writeback:0kBmapped:4kB shmem:0kB slab_reclaimable:48208kB slab_unreclaimable:11284kBkernel_stack:1696kB pagetables:0kB unstable:0kB bounce:0kB free_cma:0kBwriteback_tmp:0kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 0 9247 9247
HighMem free:694940kB min:512kBlow:15208kB high:29908kB active_anon:88516kB inactive_anon:2580kBactive_file:133940kB inactive_file:239184kB unevictable:0kB isolated(anon):0kBisolated(file):0kB present:1183624kB managed:1183624kB mlocked:0kB dirty:0kBwriteback:0kB mapped:44828kB shmem:3568kB slab_reclaimable:0kBslab_unreclaimable:0kB kernel_stack:0kB pagetables:3180kB unstable:0kBbounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 0 0 0
DMA: 1*4kB (U) 1*8kB (U) 1*16kB (U)0*32kB 2*64kB (U) 1*128kB (U) 1*256kB (U) 0*512kB 1*1024kB (U) 1*2048kB (R)3*4096kB (M) = 15900kB
Normal: 1*4kB (M) 6*8kB (UEM)3*16kB (UM) 2*32kB (EM) 2*64kB (UE) 2*128kB (UE) 2*256kB (UM) 2*512kB (UE)1*1024kB (M) 1*2048kB (U) 154*4096kB (MR) = 635940kB
HighMem: 59*4kB (UM) 10*8kB (UM) 2*16kB(M) 58*32kB (UM) 48*64kB (UM) 4*128kB (UM) 2*256kB (UM) 1*512kB (M) 0*1024kB0*2048kB 168*4096kB (UMR) = 694940kB
Node 0 hugepages_total=0hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
134350 total pagecache pages
0 pages in swap cache
Swap cache stats: add 0, delete 0, find0/0
Free swap = 1045500kB
Total swap = 1045500kB
524287 pages RAM
295938 pages HighMem
8303 pages reserved
647658 pages shared
93503 pages non-shared
root@ubuntu:/home/linux#
主要关注如下几个参数:
active_anon:匿名映射的页,这些映射是与文件无关的
active_file:文件映射的页,这些映射和文件有关
mapped:设备和文件映射的大小
slab_reclaimable:内核数据结构缓存的大小,可减少申请和释放内存带来的消耗
active_anon + active_file + mapped = 应用所使用的大小
active_anon + active_file + mapped +slab_reclaimable = 目前所使用的所有内存大小
另外我们一般还会关注:
Normal: 1*4kB (M) 6*8kB (UEM)3*16kB (UM) 2*32kB (EM) 2*64kB (UE) 2*128kB (UE) 2*256kB (UM) 2*512kB (UE)1*1024kB (M) 1*2048kB (U) 154*4096kB (MR) = 635940kB
这里是buddy system(伙伴系统)的内存信息,如果这里比较大块的内存不多,也很容易出现内存申请失败,或者触发OOM问题
一般来说内核程序中对小于一页的小块内存的请求才通过Slab分配器提供的接口Kmalloc来完成。因为slab分配的缓存都是比较小块的缓存,所以一般情况下我们分析内存性能时,对这里不会太关注,因为其对系统整体内存性能影响不会太大,并且内核中的kmalloc相对问题较少,应用层的问题较多。
不过可以通过如下信息获取slab缓存的使用情况:
root@ubuntu:/home/linux# cat/proc/slabinfo
查看slab信息,除了看slabinfo文件外,还可以执行/usr/bin/slabtop命令:
以上是一个/proc/slabinfo文件的信息
root@ubuntu:/home/linux#/usr/bin/slabtop
Active / Total Objects (% used) : 311009 / 312759 (99.4%)
Active / Total Slabs (% used) : 7308 / 7308 (100.0%)
Active / Total Caches (% used) : 66 / 100 (66.0%)
Active / Total Size (% used) : 58479.13K / 58915.22K (99.3%)
Minimum / Average / Maximum Object : 0.01K /0.19K / 8.00K
OBJS ACTIVE USE OBJ SIZE SLABS OBJ/SLAB CACHE SIZE NAME
73949 73949 100% 0.05K 1013 73 4052K buffer_head
66976 66686 99% 0.12K 2093 32 8372K dentry
47100 47100 100% 0.63K 1884 25 30144K ext4_inode_cache
该命令的输出字段的意义:
OBJS ― The total number of objects(memory blocks), including those in use (allocated), and some spares not inuse.
ACTIVE ― The number of objects (memoryblocks) that are in use (allocated).
USE ― Percentage of total objects thatare active. ((ACTIVE/OBJS)(100))
OBJ SIZE ― The size of the objects.
SLABS ― The total number of slabs.
OBJ/SLAB ― The number of objects thatfit into a slab.
CACHE SIZE ― The cache size of theslab.
NAME ― The name of the slab.
对于该文件,比较重要的是Active、Active(anon)、Active(file)、Mapped、Slab,类似于sysrq-trigger中所说,存在如下计算关系:
Active = Active(anon) + Active(file)
Active(anon)+Ac tive(file)+Mapped = 应用
Active(anon)+Ac tive(file)+Mapped +Slab= 系统总共使用内存
5.5.2 meminfo文件各字段说明
$cat /proc/meminfo
MemTotal: 2052440 kB //总内存
MemFree: 50004 kB //空闲内存
Buffers: 19976 kB //给文件的缓冲大小
Cached: 436412 kB //高速缓冲存储器(http://baike.baidu.com/view/496990.htm)使用的大小
SwapCached: 19864 kB //被高速缓冲存储用的交换空间大小
Active: 1144512 kB //活跃使用中的高速缓冲存储器页面文件大小
Inactive: 732788 kB //不经常使用的高速缓冲存储器页面文件大小
Active(anon): 987640 kB //anon:不久
Inactive(anon): 572512 kB
Active(file): 156872 kB
Inactive(file): 160276 kB
Unevictable: 8 kB
Mlocked: 8 kB
HighTotal: 1177160 kB //The total and free amountof memory, in kilobytes, that is not directly mapped into kernel space.
HighFree: 7396 kB // The HighTotal value canvary based on the type of kernel used.
LowTotal: 875280 kB // The total and free amountof memory, in kilobytes, that is directly mapped into kernel space. used.
LowFree: 42608 kB //The LowTotal value canvary based on the type of kernel
SwapTotal: 489940 kB //交换空间总大小
SwapFree: 450328 kB //空闲交换空间
Dirty: 104 kB //等待被写回到磁盘的大小
Writeback: 0 kB //正在被写回的大小
AnonPages: 1408256 kB //未映射的页的大小
Mapped: 131964 kB //设备和文件映射的大小
Slab: 37368 kB //内核数据结构缓存的大小,可减少申请和释放内存带来的消耗
SReclaimable: 14164 kB //可收回slab的大小
SUnreclaim: 23204 kB //不可收回的slab的大小23204+14164=37368
PageTables: 13308 kB //管理内存分页的索引表的大小
NFS_Unstable: 0 kB //不稳定页表的大小
Bounce: 0 kB //bounce:退回
WritebackTmp: 0 kB //
CommitLimit: 1516160 kB
Committed_AS: 2511900 kB
VmallocTotal: 122880 kB //虚拟内存大小
VmallocUsed: 28688 kB //已经被使用的虚拟内存大小
VmallocChunk: 92204 kB
HugePages_Total: 0//大页面的分配
HugePages_Free: 0
HugePages_Rsvd: 0
HugePages_Surp: 0
Hugepagesize: 2048 kB
DirectMap4k: 10232 kB
DirectMap2M: 899072 kB
VIRT:virtual memory usage 虚拟内存
1、进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据等
2、假如进程申请100m的内存,但实际只使用了10m,那么它会增长100m,而不是实际的使用量
RES:resident memory usage常驻内存(物理内存)
1、进程当前使用的内存大小,但不包括swap out
2、包含其他进程的共享
3、如果申请100m的内存,实际使用10m,它只增长10m,与VIRT相反
4、关于库占用内存的情况,它只统计加载的库文件所占内存大小
SHR:shared memory 共享内存
1、除了自身进程的共享内存,也包括其他进程的共享内存
2、虽然进程只使用了几个共享库的函数,但它包含了整个共享库的大小
3、计算某个进程所占的物理内存大小公式:RES