1、通過free 看 剩餘記憶體
# free
total used free shared buffers
Mem: 2065866752 1268113408 797753344 0 9060352
-/+ buffers/cache: 1259053056 806813696
Swap: 524283904 0 524283904
假如通過“Free”檢視記憶體幾乎耗盡,但通過top/ps指令卻看不出來使用者态應用程式占用太多的記憶體空間, 那麼核心子產品可能發生了記憶體洩露
# top -m 5
User 4%, System 2%, IOW 0%, IRQ 0%
User 49 + Nice 0 + Sys 32 + Idle 1120 + IOW 0 + IRQ 0 + SIRQ 1 = 1202
PID USER PR NI CPU% S #THR VSS RSS PCY Name
4264 system 18 -2 2% S 95 1765108K 98260K fg system_server
5145 u0_a41 20 0 2% S 41 1692144K 65372K bg com.douyu.xl.douyutv
7063 root 20 0 0% R 1 4532K 1548K fg top
2602 root RT 0 0% D 1 0K 0K fg vdec-core
2、檢視Slab 記憶體
SLAB是Linux核心中按照對象大小進行配置設定的記憶體配置設定器。
通過SLAB的資訊來檢視核心子產品占用的記憶體空間:
方法1. 檢視meminfo檔案
# cat /proc/meminfo | grep Slab
Slab: 121588 kB
++++++++++++++++++++++++++++++++++++++++++++++++++++++
方法2. 檢視slabinfo檔案
# cat /proc/slabinfo
slabinfo - version: 2.1
# name : tunables : slabdata
cifs_small_rq 31 32 448 8 1 : tunables 54 27 8 : slabdata 4 4 0
cifs_request 5 5 16512 1 8 : tunables 8 4 0 : slabdata 5 5 0
cifs_oplock_structs 0 0 64 59 1 : tunables 120 60 8 : slabdata 0 0 0
......
size-32 29904 29904 32 112 1 : tunables 120 60 8 : slabdata 267 267 0
kmem_cache 156 156 2688 1 1 : tunables 24 12 8 : slabdata 156 156 0
一般檢視slabinfo檔案就足以,如果發現slabinfo中占用記憶體過大,那基本可以斷定,核心子產品出現了記憶體洩露了
還有個指令 slabinfo 也是可以看,其實也是去讀 /proc/slabinfo 後可視化出來
3.Kmemleak工具
Demo:
看看下面這個函數是哪裡導緻的記憶體洩漏呢?
char *wr_pr_debug_begin(u8 const *data, u32 len, char *string)
{
int ii;
string = kmalloc(len * 2 + 1, GFP_KERNEL);
for (ii = 0; ii < len; ii++)
sprintf(&string[ii * 2], "%02X", data[ii]);
string[len * 2] = 0;
return string;
}
char *wr_pr_debug_end(char *string)
{
kfree(string);
return "";
}
void test()
{
char *read = 0;
pr_debug("%s RD%02X%02X%02X -> %s%s\n", st->hw->name,
i2c_addr, reg, length,
wr_pr_debug_begin(data, length, read),
wr_pr_debug_end(read));
}
一眼可能不容易看出上面的有什麼問題,有kmalloc,有kfree 成對出現的。
問題正好出在 pr_debug 這個函數中的參數傳遞, 熟悉函數調用傳參的人應該會知道編譯器一般對參數的處理采用堆棧的方式,是一個先進後出的過程,這樣參數的執行一般是逆序的(由于編譯器實作的不同,這個過程不是确定的),這樣kfree會在kmalloc之前運作,導緻每次運作都會洩漏一點記憶體。
參考資料