1。 記憶體使用情況分析

1。1 系統總記憶體分析

透過cat /proc/meminfo,可用的物理記憶體=MemFree+Buffers+Cached。

MemTotal: 5933132 kB

MemFree: 4485932 kB

MemAvailable: 4822944 kB

Buffers: 122148 kB

Cached: 630048 kB

SwapCached: 0 kB

Active: 806136 kB

Inactive: 461288 kB

Active(anon): 516344 kB

Inactive(anon): 230112 kB

Active(file): 289792 kB

Inactive(file): 231176 kB

Unevictable: 32 kB

Mlocked: 32 kB

SwapTotal: 7999484 kB

SwapFree: 7999484 kB

Dirty: 204 kB

Writeback: 0 kB

AnonPages: 515264 kB

echo 3 > /proc/sys/vm/drop_caches,會清理系統的cache。

Writing to this will cause the kernel to drop clean caches, dentries and inodes from memory, causing that memory to become free。

1-to free pagecache, 2-to free dentries and inodes, 3-to free pagecache, dentries and inodes。

1。2 程序記憶體分析

cat /proc/{pid}/maps

2。1 記憶體洩露型別

1。

常發性記憶體洩漏

發生記憶體洩漏的程式碼會被多次執行到,每次被執行的時候都會導致一塊記憶體洩漏

2。

偶發性記憶體洩漏

發生記憶體洩漏的程式碼只有在某些特定環境或操作過程下才會發生。常發性和偶發性是相對的。對於特定的環境,偶發性的也許就變成了常發性的。所以測試環境和測試方法對檢測記憶體洩漏至關重要

3。

一次性記憶體洩漏

發生記憶體洩漏的程式碼只會被執行一次,或者由於演算法上的缺陷,導致總會有一塊且僅有一塊記憶體發生洩漏

4。

隱式記憶體洩漏

程式在執行過程中不停的分配記憶體,但是直到結束的時候才釋放記憶體。嚴格的說這裡並沒有發生記憶體洩漏,因為最終程式釋放了所有申請的記憶體。但是對於

一個伺服器程式,需要執行幾天,幾周甚至幾個月,不及時釋放記憶體也可能導致最終耗盡系統的所有記憶體

。所以,我們稱這類記憶體洩漏為隱式記憶體洩漏

2。2 常用記憶體洩露檢測工具

C/C++

1。 Valgrind: Debugging and profiling Linux programs, aiming at programs written in C and C++

2。 ccmalloc: Linux和Solaris下對C和C++程式的簡單的使用記憶體洩漏和malloc除錯庫

3。 LeakTracer: Linux、Solaris和HP-UX下跟蹤和分析C++程式中的記憶體洩漏

4。 Electric Fence: Linux分發版中由Bruce Perens編寫的malloc()除錯庫

5。 Leaky: Linux下檢測記憶體洩漏的程式

6。 Dmalloc: Debug Malloc Library

7。 MEMWATCH: 由Johan Lindh編寫,是一個開放原始碼C語言記憶體錯誤檢測工具,主要是透過gcc的precessor來進行

8。 KCachegrind: A visualization tool for the profiling data generated by Cachegrind and Calltree

2。3 記憶體檢測原理

3。1 Linux核心記憶體洩漏檢測kmemleak

kmemlean提供了一種檢測核心記憶體洩露的方法,當記憶體物件沒有被釋放是,將其記錄在/sys/kernel/debug/kmemleak中。

3。1。1 使能kmemleak

CONFIG_DEBUG_KMEMLEAK=y CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=400 # CONFIG_DEBUG_KMEMLEAK_TEST is not set CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=n——————預設開啟

如果沒有開啟KMEMLEAK_FULL,則使用了精簡版。完整版比較耗記憶體,精簡版適合嵌入式除錯。

3。1。2 配置獲取kmemleak結果

引數配置:

Linux記憶體使用以及記憶體洩露

off 禁用kmemleak(不可逆) stack=on 啟用任務堆疊掃描(default) stack=off 禁用任務堆疊掃描 scan=on 啟動自動記憶掃描執行緒(default) scan=off 停止自動記憶掃描執行緒 scan= 設定n秒內自動記憶掃描 scan 開啟核心掃描 clear 清除記憶體洩露報告 dump= 轉存資訊物件在 透過“kmemleak = OFF”,也可以在啟動時禁用Kmemleak在核心命令列。在初始化kmemleak之前,記憶體的分配或釋放這些動作被儲存在一個前期日誌緩衝區。這個緩衝區的大小透過配CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE設定。

Linux記憶體使用以及記憶體洩露

cat /sys/kernel/debug/kmemleak > kmemleak。txt

3。1。3 分析kmemleak洩漏情況

參考文件:

《kmemleak的使用》

《Linux Kernel Memory Leak Detection》

《Linux memory leak detection》

3。2 valgrind

Linux C/C++ Memory Leak Detection Tool

Linux 下幾款程式記憶體洩漏檢查工具

Linux下幾款C++程式中的記憶體洩露檢查工具

Linux 記憶體洩露檢測技巧

應用 Valgrind 發現 Linux 程式的記憶體問題

檢視程式記憶體空間兩種方法

一、檢視/proc/{pid}/maps檔案

二、pmap命令,原理上是一樣的

[root@info ~]# pmap 1013

什麼是記憶體洩漏

記憶體洩漏是指

程式動態申請的記憶體在使用完後沒有釋放,導致這段記憶體不能被作業系統回收再利用

例如這段程式,申請了4個位元組的空間但沒有釋放,有4個位元組的記憶體洩漏。

#include

using namespace std;

int main()

{

int *p = new int(1);

cout <<*p<

return 0

}

隨著時間的推移,洩漏的記憶體越來越多,可用的記憶體越來越少,輕則效能受損,重則系統崩潰。

一般情況下,

發生記憶體洩漏時,重啟就可以回收洩漏的記憶體。但是對於linux,通常跑的是伺服器程式,不可以隨意重啟,在記憶體洩漏問題上就要格外小心

記憶體洩漏特點

難復現 — 要執行到足夠長的時間才會暴露。

難定位 — 出錯位置是隨機的,看不出與記憶體洩漏的程式碼有什麼聯絡。

最簡單的方法

為了避免寫出記憶體洩漏的程式,通常會有這樣的程式設計規範,要求我們在

寫程式時申請和釋放成對出現的

。因為每一次申請都意味著必須有一次釋放與它相對應。

基於這個特點,一種簡單的方法就是在

程式碼中統計申請和釋放的次數,如果申請和釋放的數量不同,就認為是記憶體洩漏了

#include “stdio。h”

#include “stdlib。h”

int malloc_count, free_count;

void * my_malloc(int size)

{

malloc_count++;

return malloc(size);

}

void my_free(void *p)

{

free_count++;

free(p);

}

int main()

{

count = 0;

int *p1 = (int *)my_malloc(sizeif(int))

int *p2 = (int *)my_malloc(sizeif(int))

printf(“%d, %d”, p1, p2);

my_free(p1);

if(malloc_count != free_count)

printf(“memory leak!\n”);

return 0

}

方法分析

優點:

直觀,容易理解,容易實現

缺點:

1。該方法要求執行結束時對執行中產生的列印分析才能知道結果。

2。該方法要求封裝所有申請和釋放空間的函式,並在呼叫的地方修改成呼叫封裝後的函式。雖然C中申請/釋放記憶體介面並不多,但是對於一個大型的專案,呼叫這些介面的地方卻是很多的,要全部替換是一個比較大的工作量。

3。只對C語言適用,不能應用於C++

4。對於

所呼叫的庫不適用

。如果希望應用於庫,則要修改庫程式碼

5。只能檢測是否洩漏,卻沒有具體資訊,比如洩漏了多少空間

6。不能說明是哪一行程式碼引起了洩漏

Linux檢測程式記憶體洩漏

1。安裝valgrind:

這是一款開源的程式記憶體檢測工具,mtrace為記憶體分配函式(malloc, realloc, memalign,free)安裝hook函式。這些

hook函式記錄記憶體的申請和釋放的trace資訊

Valgrind詳解:

Linux記憶體使用以及記憶體洩露

Valgrind包括以下一些工具:

1。Memcheck:這是valgrind應用最廣泛的工具,一個重量級的記憶體檢查器,能夠給發現開發中絕大多數的記憶體錯誤使用的情況,比如:使用未初始化

2。callgrind:它主要用來檢查程式中函式中呼叫過程中出現的問題

3。cachegrind:它主要用來檢查程式中快取使用出現的問題

4。Helgrind:它主要用來檢查多執行緒中出現的競爭問題

5。Massif:它主要用來檢查程式中堆疊使用中出現的問題

6。Extension:可以使用core提供的功能,自己編寫特定的記憶體除錯工具

2。mtrace命令

man 3 mtrace 可以在man 手冊中檢視該函式

mtrace 也有對應的命令,其使用方式為:

一.將環境變數MALLOC_TRACE設定為所需輸出檔案的路徑名

Linux記憶體使用以及記憶體洩露

二.在需要檢測的原始碼中引入mcheck。h標頭檔案

1.在分配記憶體之前呼叫mtrace(); ,一般在main函式的開頭呼叫

2.在結束檢測的地方呼叫muntrace(); ,一般在return之前呼叫

3.編譯程式時需要加上-g 選項

#include

#include

#include

int main()

{

mtrace();

int *p = NULL;

p =(int *)malloc(sizeof(int) * 1);

//free(p);//未free,記憶體洩漏

muntrace();

return 0;

}

4。記憶體洩漏資訊將在MALLOC_TRACE環境變數指定的檔案中報告,需要使用mtrace命令將資訊轉換。

Valgrind的最新版是3。11。0,它一般包含下列工具:

1。Memcheck

最常用的工具,用來檢測程式中出現的記憶體問題,所有對記憶體的讀寫都會被檢測到,一切對malloc()/free()/new/delete的呼叫都會被捕獲。所以,它能檢測以下問題:

對未初始化記憶體的使用;

讀/寫釋放後的記憶體塊;

讀/寫超出malloc分配的記憶體塊;

讀/寫不適當的棧中記憶體塊;

記憶體洩漏,指向一塊記憶體的指標永遠丟失;

不正確的malloc/free或new/delete匹配;

memcpy()相關函式中的dst和src指標重疊。

2。Callgrind

和gprof類似的分析工具,但它對程式的執行觀察更是入微,能給我們提供更多的資訊。和gprof不同,它不需要在編譯原始碼時附加特殊選項,但加上除錯選項是推薦的。Callgrind收集程式執行時的一些資料,建立函式呼叫關係圖,還可以有選擇地進行cache模擬。在執行結束時,它會把分析資料寫 入一個檔案。callgrind_annotate可以把這個檔案的內容轉化成可讀的形式。

3。Cachegrind

Cache分析器,它模擬CPU中的一級快取I1,Dl和二級快取,能夠精確地指出程式中cache的丟失和命中。如果需要,它還能夠為我們提供 cache丟失次數,記憶體引用次數,以及每行程式碼,每個函式,每個模組,整個程式產生的指令數。這對最佳化程式有很大的幫助。

4。Helgrind

它主要用來檢查多執行緒程式中出現的競爭問題。Helgrind尋找記憶體中被多個執行緒訪問,而又沒有一貫加鎖的區域,這些區域往往是執行緒之間失去同步的地 方,而且會導致難以發掘的錯誤。Helgrind實現了名為“Eraser”的競爭檢測演算法,並做了進一步改進,減少了報告錯誤的次數。不過,Helgrind仍然處於實驗階段。

5。Massif

堆疊分析器,它能測量程式在堆疊中使用了多少記憶體,告訴我們堆塊,堆管理塊和棧的大小。Massif能幫助我們減少記憶體的使用,在帶有虛擬記憶體的現代系統中,它還能夠加速我們程式的執行,減少程式停留在交換區中的機率。

此外,lackey和nulgrind也會提供。Lackey是小型工具,很少用到;Nulgrind只是為開發者展示如何建立一個工具。

1。3 原理

Memcheck 能夠檢測出記憶體問題,

關鍵在於其建立了兩個全域性表

。Valid-Value 表

對於程序的整個地址空間中的每一個位元組(byte),都有與之對應的 8 個 bits;對於CPU的每個暫存器,也有一個與之對應的bit向量。這些bits負責記錄該位元組或者暫存器值是否具有有效的、已初始化的值。

Valid-Address 表

對於程序整個地址空間中的每一個位元組(byte),還有與之對應的1個bit,負責記錄該地址是否能夠被讀寫。

檢測原理:

當要讀寫記憶體中某個位元組時,首先檢查這個位元組對應的 A bit。如果該A bit顯示該位置是無效位置,memcheck則報告讀寫錯誤。

核心(core)類似於一個虛擬的 CPU 環境,這樣當記憶體中的某個位元組被載入到真實的 CPU 中時,該位元組對應 的 V bit 也被載入到虛擬的 CPU 環境中。一旦暫存器中的值,被用來產生記憶體地址,或者該值能夠影響程式輸出,則 memcheck 會檢查對應的V bits,如果該值尚未初始化,則會報告使用未初始化記憶體錯誤。

2 安裝使用

2。1安裝

從官網http://www。valgrind。org下載最新版本(當前3。11)

#tar xvf valgrind-3。11。1。tar。bz2

#cd valgrind-3。11。1

#。/configure ——prefix=/usr/local/valgrind——指定安裝目錄

#make

#make install

2。2 命令介紹

用法:valgrind[options] prog-and-args [options]: 常用選項,適用於所有Valgrind工具

-tool= 最常用的選項。執行 valgrind中名為toolname的工具。預設memcheck。

h –help 顯示幫助資訊。

-version 顯示valgrind核心的版本,每個工具都有各自的版本。

q –quiet 安靜地執行,只打印錯誤資訊。

v –verbose 更詳細的資訊, 增加錯誤數統計。

-trace-children=no|yes 跟蹤子執行緒? [no]

-track-fds=no|yes 跟蹤開啟的檔案描述?[no]

-time-stamp=no|yes 增加時間戳到LOG資訊? [no]

-log-fd= 輸出LOG到描述符檔案 [2=stderr]

-log-file= 將輸出的資訊寫入到filename。PID的檔案裡,PID是執行程式的進行ID

-log-file-exactly= 輸出LOG資訊到 file

-log-file-qualifier= 取得環境變數的值來做為輸出資訊的檔名。 [none]

-log-socket=ipaddr:port 輸出LOG到socket ,ipaddr:port

LOG資訊輸出:

-xml=yes 將資訊以xml格式輸出,只有memcheck可用

-num-callers= show callers in stack traces [12]

-error-limit=no|yes 如果太多錯誤,則停止顯示新錯誤? [yes]

-error-exitcode= 如果發現錯誤則返回錯誤程式碼 [0=disable]

-db-attach=no|yes 當出現錯誤,valgrind會自動啟動偵錯程式gdb。[no]

-db-command= 啟動偵錯程式的命令列選項[gdb -nw %f %p]

適用於Memcheck工具的相關選項:

-leak-check=no|summary|full 要求對leak給出詳細資訊? [summary]

-leak-resolution=low|med|high how much bt merging in leak check [low]

-show-reachable=no|yes show reachable blocks in leak check? [no]

在實際的專案中,最難纏的問題就是記憶體洩漏,當然還有panic之類的,記憶體洩漏分為兩部分使用者空間的和核心空間的。

我們就分別從這兩個層面分析一下。

使用者空間檢視記憶體洩漏和解決都相對簡單

。定位問題的方法和工具也很多相對容易。我們來看看。

1。 檢視記憶體資訊

cat /proc/meminfo、free、cat /proc/slabinfo等

2。 檢視程序的狀態資訊

top、ps、cat /proc/pid/maps/status/fd等

通常我們定位問題先在shell下ps檢視當前執行程序的狀態,嵌入式上可能顯示的資訊會少一些。

[root@localhost kthread]# ps auxw|more

USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

root 1 0。0 0。0 19396 1556 ? Ss May16 0:05 /sbin/init

我們可以很清晰看到VMZ和RSS的對比資訊。

VMZ就是這個程序申請的虛擬地址空間,而RSS是這個程序佔用的實際物理記憶體空間.

通常一個程序如果有記憶體洩露VMZ會不斷增大,相對的物理記憶體也會增加,如果是這樣一般需要檢查malloc/free是否匹配。根據程序ID我們可以檢視詳細的VMZ相關的資訊。例:

1。 root@hos-machine:~# cat /proc/1298/status

2。 Name: sshd

3。 State: S (sleeping)

4。 Tgid: 1298

5。 Ngid: 0

6。 Pid: 1298

7。 PPid: 1

8。 TracerPid: 0

9。 Uid: 0 0 0 0

10。 Gid: 0 0 0 0

11。 FDSize: 128

12。 Groups:

13。 NStgid: 1298

14。 NSpid: 1298

15。 NSpgid: 1298

16。 NSsid: 1298

17。 VmPeak: 65620 kB

18。 VmSize: 65520 kB

19。 VmLck: 0 kB

20。 VmPin: 0 kB

21。 VmHWM: 5480 kB

22。 VmRSS: 5452 kB

23。 VmData: 580 kB

24。 VmStk: 136 kB

25。 VmExe: 764 kB

26。 VmLib: 8316 kB

27。 VmPTE: 148 kB

28。 VmPMD: 12 kB

29。 VmSwap: 0 kB

30。 HugetlbPages: 0 kB

31。 Threads: 1

32。 SigQ: 0/7814

33。 SigPnd: 0000000000000000

34。 ShdPnd: 0000000000000000

35。 SigBlk: 0000000000000000

36。 SigIgn: 0000000000001000

37。 SigCgt: 0000000180014005

38。 CapInh: 0000000000000000

39。 CapPrm: 0000003fffffffff

40。 CapEff: 0000003fffffffff

41。 CapBnd: 0000003fffffffff

42。 CapAmb: 0000000000000000

43。 Seccomp: 0

44。 Cpus_allowed: ffffffff,ffffffff

45。 Cpus_allowed_list: 0-63

46。 Mems_allowed: 00000000,00000001

47。 Mems_allowed_list: 0

48。 voluntary_ctxt_switches: 1307

49。 nonvoluntary_ctxt_switches: 203

如果我們想檢視這個程序打開了多少檔案可以

[root@localhost kthread]# ls -l /proc/184172/fd/* | wc

214 2354 17293

順帶:(檢視程序開啟的所有檔案)

[root@localhost kthread]#

ls -l /proc/184172/fd/* |more

lr-x————。 1 root root 64 Jul 10 16:35 /proc/184172/fd/0 -> /dev/null

l-wx————。 1 root root 64 Jul 10 16:35 /proc/184172/fd/1 -> /usr/local/mm/mm。log

lrwx————。 1 root root 64 Jul 10 16:35 /proc/184172/fd/10 -> socket:[13690382]

lrwx————。 1 root root 64 Jul 10 16:35 /proc/184172/fd/100 -> socket:[13690549]

檢視程序詳細的記憶體對映資訊

cat /proc/7393/maps

[root@localhost kthread]# cat /proc/184172/maps

00400000-00455000 r-xp 00000000 fd:05 1441820 /usr/local/mm/ms

00654000-00655000 rw-p 00054000 fd:05 1441820 /usr/local/mm/ms

00655000-00658000 rw-p 00000000 00:00 0

02205000-1a218000 rw-p 00000000 00:00 0 [heap]

3000600000-3000603000 r-xp 00000000 fd:00 143299 /lib64/libcom_err。so。2。1

3000603000-3000802000 ——-p 00003000 fd:00 143299 /lib64/libcom_err。so。2。1

我們看一下meminfo各個註釋:參考documentation/filesystem/proc。txt

1。 MemTotal: Total usable ram (i。e。 physical ram minus a few reserved bits and the kernel binary code)

2。 MemFree: The sum of LowFree+HighFree

3。 Buffers: Relatively temporary storage for raw disk blocks shouldn‘t get tremendously large (20MB or so)

4。 Cached: in-memory cache for files read from the disk (the pagecache)。 Doesn’t include

5。 SwapCached SwapCached: Memory that once was swapped out, is swapped back in but still also is in the swapfile (if memory is needed it

6。 doesn‘t need to be swapped out AGAIN because it is already in the swapfile。 This saves I/O)

7。 Active: Memory that has been used more recently and usually not reclaimed unless absolutely necessary。

8。 Inactive: Memory which has been less recently used。 It is more eligible to be reclaimed for other purposes

9。 HighTotal:

10。 HighFree: Highmem is all memory above ~860MB of physical memory Highmem areas are for use by userspace programs, or

11。 for the pagecache。 The kernel must use tricks to access this memory, making it slower to access than lowmem。

12。 LowTotal:

13。 LowFree: Lowmem is memory which can be used for everything that highmem can be used for, but it is also available for the

14。 kernel’s use for its own data structures。 Among many other things, it is where everything from the Slab is

15。 allocated。 Bad things happen when you‘re out of lowmem。

16。 SwapTotal: total amount of swap space available

17。 SwapFree: Memory which has been evicted from RAM, and is temporarily on the disk

18。 Dirty: Memory which is waiting to get written back to the disk

19。 Writeback: Memory which is actively being written back to the disk

20。 AnonPages: Non-file backed pages mapped into userspace page tables

21。 AnonHugePages: Non-file backed huge pages mapped into userspace page tables

22。 Mapped: files which have been mmaped, such as libraries

23。 Slab: in-kernel data structures cache

24。 SReclaimable: Part of Slab, that might be reclaimed, such as caches

25。 SUnreclaim: Part of Slab, that cannot be reclaimed on memory pressure

26。 PageTables: amount of memory dedicated to the lowest level of page tables。

27。 NFS_Unstable: NFS pages sent to the server, but not yet committed to stable storage

28。 Bounce: Memory used for block device “bounce buffers”

29。 WritebackTmp: Memory used by FUSE for temporary writeback buffers

30。 CommitLimit: Based on the overcommit ratio (’vm。overcommit_ratio‘), this is the total amount of memory currently available to

31。 be allocated on the system。 This limit is only adhered to if strict overcommit accounting is enabled (mode 2 in

32。 ’vm。overcommit_memory‘)。

33。 The CommitLimit is calculated with the following formula: CommitLimit = (’vm。overcommit_ratio‘ * Physical RAM) + Swap

34。 For example, on a system with 1G of physical RAM and 7G

35。 of swap with a `vm。overcommit_ratio` of 30 it would

36。 yield a CommitLimit of 7。3G。

37。 For more details, see the memory overcommit documentation in vm/overcommit-accounting。

38。 Committed_AS: The amount of memory presently allocated on the system。 The committed memory is a sum of all of the memory which

39。 has been allocated by processes, even if it has not been

40。 “used” by them as of yet。 A process which malloc()’s 1G

41。 of memory, but only touches 300M of it will only show up as using 300M of memory even if it has the address space

42。 allocated for the entire 1G。 This 1G is memory which has been “committed” to by the VM and can be used at any time

43。 by the allocating application。 With strict overcommit enabled on the system (mode 2 in ‘vm。overcommit_memory’),

44。 allocations which would exceed the CommitLimit (detailed above) will not be permitted。 This is useful if one needs

45。 to guarantee that processes will not fail due to lack of memory once that memory has been successfully allocated。

46。 VmallocTotal: total size of vmalloc memory area

47。 VmallocUsed: amount of vmalloc area which is used

48。 VmallocChunk: largest contiguous block of vmalloc area which is free

我們只需要關注幾項就ok。 buffers/cache/slab/active/anonpages

Active= Active(anon) + Active(file) (同樣Inactive)

AnonPages: Non-file backed pages mapped into userspace page tables\

buffers和cache的區別註釋說的很清楚了。

有時候不是記憶體洩露,同樣也會讓系統崩潰,比如cache、buffers等佔用的太多,開啟太多檔案

而等待系統自動回收是一個非常漫長的過程.

從proc目錄下的meminfo檔案瞭解到當前系統記憶體的使用情況彙總,其中

可用的物理記憶體=memfree+buffers+cached,當memfree不夠時,核心會透過回寫機制(pdflush執行緒)把cached和buffered記憶體回寫到後備儲存器

,從而釋放相關記憶體供程序使用,或者透過手動方式顯式釋放cache記憶體

1。 drop_caches

2。 Writing to this will cause the kernel to drop clean caches, dentries and inodes from memory, causing that memory to become free。

3。 To free pagecache:

4。 echo 1 > /proc/sys/vm/drop_caches

5。 To free dentries and inodes:

6。 echo 2 > /proc/sys/vm/drop_caches

7。 To free pagecache, dentries and inodes:

8。 echo 3 > /proc/sys/vm/drop_caches

9。 As this is a non-destructive operation and dirty objects are not freeable, the user should run `sync`first

使用者空間記憶體檢測也可以透過mtrace來檢測用法也非常簡單

。 包括比較有名的工具valgrind、以及dmalloc、memwatch等。各有特點。

核心記憶體洩露

定位比較複雜

,先判斷是否是核心洩露了,然後在具體定位什麼操作,然後再排查一些可疑的模組,核心記憶體操作基本都是kmalloc即透過slab/slub/slob機制,所以如果meminfo裡slab一直增長那麼很有可能是核心的問題。我們可以

更加詳細的檢視slab資訊cat /proc/slabinfo

如果支援slabtop更好,基本可以判斷核心是否有記憶體洩漏,並且是在操作什麼物件的時候發生的。

1。 cat /proc/slabinfo

2。 slabinfo - version: 2。1

3。 # name : tunables : slabdata

4。 fuse_request 0 0 288 28 2 : tunables 0 0 0 : slabdata 0 0 0

5。 fuse_inode 0 0 448 18 2 : tunables 0 0 0 : slabdata 0 0 0

6。 fat_inode_cache 0 0 424 19 2 : tunables 0 0 0 : slabdata 0 0 0

7。 fat_cache 0 0 24 170 1 : tunables 0 0 0 : slabdata 0 0 0

在核心的配置中裡面已經支援了一部分memleak自動檢查的選項,可以開啟來進行跟蹤除錯。

這裡沒有深入的東西,算是拋磚引玉吧~。