5. 內存問題排查手段及相關文件介紹【重點】
對於內存問題排查,或者OOM問題排查,一般會涉及到如下文件,下面將如下文件的分析和設置介紹一下,這也是本文檔的重點,后面排查內存信息還是要根據這些文件信息來排查。其實未必是有內存泄露,也可能是一些策略有問題,比如線程數目的增加,buffer的申請、釋放時間交集等。
5.1 /proc/sys/vm/min_free_kbytes
min_free_kbytes用來確定系統開始回收內存的閥值,控制系統的空閑內存。值越高,內核越早開始回收內存,空閑內存越高。
可以使用如下方式:echo 65535 > /proc/sys/vm/min_free_kbytes將系統保留內存設置為6M。
5.2 /proc/sys/vm/drop_caches
清系統緩存:
#echo 1 > /proc/sys/vm/drop_caches 清理頁緩存
#echo 2 > /proc/sys/vm/drop_caches 清理文件緩存
#echo 3 > /proc/sys/vm/drop_caches 清理也緩存和文件緩存
5.3 /proc/sysrq-trigger
當一個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出來
5.3.1對echo m > /proc/sysrq-trigger輸出的解析
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問題
5.4 cat /proc/slabinfo
一般來說內核程序中對小於一頁的小塊內存的請求才通過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.
5.5 cat /proc/meminfo
5.5.1 重要信息
對於該文件,比較重要的是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
5.6 top信息
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 – SHR
4、swap out后,它將會降下來
DATA
1、數據占用的內存。如果top沒有顯示,按f鍵可以顯示出來。
2、真正的該程序要求的數據空間,是真正在運行中要使用的。
top 運行中可以通過 top 的內部命令對進程的顯示方式進行控制。內部命令如下:
s – 改變畫面更新頻率
l – 關閉或開啟第一部分第一行 top 信息的表示
t – 關閉或開啟第一部分第二行 Tasks 和第三行Cpus 信息的表示
m – 關閉或開啟第一部分第四行 Mem 和 第五行 Swap信息的表示
N – 以 PID 的大小的順序排列表示進程列表
P – 以 CPU 占用率大小的順序排列進程列表
M – 以內存占用率大小的順序排列進程列表
h – 顯示幫助
n – 設置在進程列表所顯示進程的數量
q – 退出 top
s – 改變畫面更新周期
序號 列名 含義
a PID 進程id
b PPID 父進程id
c RUSER Real user name
d UID 進程所有者的用戶id
e USER 進程所有者的用戶名
f GROUP 進程所有者的組名
g TTY 啟動進程的終端名。不是從終端啟動的進程則顯示為 ?
h PR 優先級
i NI nice值。負值表示高優先級,正值表示低優先級
j P 最后使用的CPU,僅在多CPU環境下有意義
k %CPU 上次更新到現在的CPU時間占用百分比
l TIME 進程使用的CPU時間總計,單位秒
m TIME+ 進程使用的CPU時間總計,單位1/100秒
n %MEM 進程使用的物理內存百分比
o VIRT 進程使用的虛擬內存總量,單位kb。VIRT=SWAP+RES
p SWAP 進程使用的虛擬內存中,被換出的大小,單位kb。
q RES 進程使用的、未被換出的物理內存大小,單位kb。RES=CODE+DATA
r CODE 可執行代碼占用的物理內存大小,單位kb
s DATA 可執行代碼以外的部分(數據段+棧)占用的物理內存大小,單位kb
t SHR 共享內存大小,單位kb
u nFLT 頁面錯誤次數
v nDRT 最后一次寫入到現在,被修改過的頁面數。
w S 進程狀態。(D=不可中斷的睡眠狀態,R=運行,S=睡眠,T=跟蹤/停止,Z=僵屍進程)
x COMMAND 命令名/命令行
y WCHAN 若該進程在睡眠,則顯示睡眠中的系統函數名
z Flags 任務標志,參考 sched.h
默認情況下僅顯示比較重要的 PID、USER、PR、NI、VIRT、RES、SHR、S、%CPU、%MEM、TIME+、COMMAND 列。可以通過下面的快捷鍵來更改顯示內容。
通過 f 鍵可以選擇顯示的內容。按 f 鍵之后會顯示列的列表,按 a-z 即可顯示或隱藏對應的列,最后按回車鍵確定。
按 o 鍵可以改變列的顯示順序。按小寫的 a-z 可以將相應的列向右移動,而大寫的 A-Z 可以將相應的列向左移動。最后按回車鍵確定。
按大寫的 F 或 O 鍵,然后按 a-z 可以將進程按照相應的列進行排序。而大寫的 R 鍵可以將當前的排序倒轉。
5.7 free命令
free的輸出一共有四行,第四行為交換區的信息,分別是交換的總量(total),使用量(used)和有多少空閑的交換區(free)
free輸出地第二行和第三行都是說明內存使用情況的。第一列是總量(total),第二列是使用量(used),第三列是可用量(free)。
第2行的輸出時從操作系統(OS)來看的。也就是說,從OS的角度來看,計算機上一共有:
24677460KB(缺省時free的單位為KB)物理內存;
在這些物理內存中有23276064KB被使用了;
還用1401396KB是可用的;
第3行:
-buffers/cache,表示一個應用程序認為系統被用掉多少內存;
+buffers/cache,表示一個應用程序認為系統還有多少內存;
5.8 /proc/sys/vm/目錄下的其他文件
1. /proc/sys/vm/block_dump
該文件表示是否打開Block Debug模式,用於記錄所有的讀寫及DirtyBlock寫回動作。
缺省設置:0,禁用BlockDebug模式
2. /proc/sys/vm/dirty_background_ratio
該文件表示臟數據到達系統整體內存的百分比,此時觸發pdflush進程把臟數據寫回磁盤。
缺省設置:10
3. /proc/sys/vm/dirty_expire_centisecs
該文件表示如果臟數據在內存中駐留時間超過該值,pdflush進程在下一次將把這些數據寫回磁盤。
缺省設置:3000(1/100秒)
4. /proc/sys/vm/dirty_ratio
該文件表示如果進程產生的臟數據到達系統整體內存的百分比,此時進程自行把臟數據寫回磁盤。
缺省設置:40
5./proc/sys/vm/dirty_writeback_centisecs
該文件表示pdflush進程周期性間隔多久把臟數據寫回磁盤。
缺省設置:500(1/100秒)
6. /proc/sys/vm/vfs_cache_pressure
該文件表示內核回收用於directory和inode cache內存的傾向;缺省值100表示內核將根據pagecache和swapcache,把directory和inode cache保持在一個合理的百分比;降低該值低於100,將導致內核傾向於保留directory和inode cache;增加該值超過100,將導致內核傾向於回收directory和inode cache
缺省設置:100
7. /proc/sys/vm/min_free_kbytes
該文件表示強制Linux VM最低保留多少空閑內存(Kbytes)。
缺省設置:724(512M物理內存)
8. /proc/sys/vm/nr_pdflush_threads
該文件表示當前正在運行的pdflush進程數量,在I/O負載高的情況下,內核會自動增加更多的pdflush進程。
缺省設置:2(只讀)
9. /proc/sys/vm/overcommit_memory
該文件指定了內核針對內存分配的策略,其值可以是0、1、2。
0, 表示內核將檢查是否有足夠的可用內存供應用進程使用;如果有足夠的可用內存,內存申請允許;否則,內存申請失敗,並把錯誤返回給應用進程。
1, 表示內核允許分配所有的物理內存,而不管當前的內存狀態如何。
2, 表示內核允許分配超過所有物理內存和交換空間總和的內存(參照overcommit_ratio)。
缺省設置:0
10. /proc/sys/vm/overcommit_ratio
該文件表示,如果overcommit_memory=2,可以過載內存的百分比,通過以下公式來計算系統整體可用內存。
系統可分配內存=交換空間+物理內存*overcommit_ratio/100
缺省設置:50(%)
11. /proc/sys/vm/page-cluster
該文件表示在寫一次到swap區的時候寫入的頁面數量,0表示1頁,1表示2頁,2表示4頁。
缺省設置:3(2的3次方,8頁)
12. /proc/sys/vm/swapiness
該文件表示系統進行交換行為的程度,數值(0-100)越高,越可能發生磁盤交換。