細說Linux內存泄漏檢測實現(xiàn)原理與實現(xiàn)_第1頁
細說Linux內存泄漏檢測實現(xiàn)原理與實現(xiàn)_第2頁
細說Linux內存泄漏檢測實現(xiàn)原理與實現(xiàn)_第3頁
細說Linux內存泄漏檢測實現(xiàn)原理與實現(xiàn)_第4頁
細說Linux內存泄漏檢測實現(xiàn)原理與實現(xiàn)_第5頁
全文預覽已結束

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第第頁細說Linux內存泄漏檢測實現(xiàn)原理與實現(xiàn)在使用沒有垃圾回收的語言時(如C/(C++)),可能由于忘記釋放內存而導致內存被耗盡,這叫

內存泄漏。由于內核也需要自己管理內存,所以也可能出現(xiàn)內存泄漏的情況。為了能夠找出導致內存泄漏的地方,(Linux)內核(開發(fā)者)開發(fā)出kmemleak功能。

下面我們來詳細介紹一下kmemleak這個功能的原理與實現(xiàn)。

kmemleak原理

首先來分析一下,什么情況會導致

內存泄漏。

1.造成內存泄漏的原因

內存泄漏的根本原因是由于用戶沒有釋放不再使用的動態(tài)申請的內存(在內核中由

memblock_alloc、kmalloc、vmalloc、kmem_cache_alloc

等函數(shù)申請的內存),那么哪些內存是不再使用的呢?一般來說,沒有被指針引用(指向)的內存都是不再使用的內存。因為這些內存已經丟失了其地址信息,從而導致內核不能再使用這些內存。

我們來看看下圖的事例:

雖然

create_obiect

函數(shù)的代碼比較長,但是邏輯卻很簡單,主要完成2件事情:

申請一個新的

kmemleak_object

對象,并且初始化其各個字段。

將新申請的

kmemleak_object

對象添加到全局紅黑樹中。

kmemleak_object

對象插入到全局紅黑樹的算法與數(shù)據(jù)結構中的平衡二叉樹算法是一致的,所以不了解的同學可以查閱相關的(資料)。

2.內存泄漏檢測

當開啟內存泄漏檢測時,內核將會創(chuàng)建一個名為

kmemleak

的內核線程來進行檢測。

在分析內存檢測的實現(xiàn)之前,我們先來了解一下關于

kmemleak_object

對象的三個概念:

白色節(jié)點:表示此對象沒有被指針引用(count

字段少于

min_count

字段)。

灰色節(jié)點:表示此對象被一個或多個指針引用(count

字段大于或等于

min_count

字段)。

黑色節(jié)點:表示此對象不需要被掃描(min_count

字段等于-1)。

接著我們來看看

kmemleak

內核線程的實現(xiàn):

static

int

kmemleak_s(can)_thread(void

*arg){

...

while

(!kthread_should_stop())

{

...

kmemleak_scan();

//

進行內存泄漏掃描

...

}

return

0;}

可以看出

kmemleak

內核線程主要通過調用

kmemleak_scan

函數(shù)來進行內存泄漏掃描。我們繼續(xù)來看看

kmemleak_scan

函數(shù)的實現(xiàn):

static

void

kmemleak_scan(void){

...

//

1)

將所有

kmemleak_object

對象的

count

字段置0,表示開始時全部是白色節(jié)點

list_f(or)_e(ac)h_entry_rcu(object,

...

}

...

//

2)

掃描數(shù)據(jù)段與未初始化數(shù)據(jù)段

scan_block(_(sd)ata,

_(eda)ta,

NULL,

1);

scan_block(__bss_start,

__bss_stop,

NULL,

1);

...

//

3)

掃描所有內存頁結構,這是由于內存頁結構也可能引用其他內存塊

for_each_online_node(i)

{

...

for

(pfn

=

start_pfn;

pfn

由于

kmemleak_scan

函數(shù)的代碼比較長,所以我們對其進行精簡。精簡后可以看出,kmemleak_scan

函數(shù)主要完成5件事情:

將系統(tǒng)中所有

kmemleak_object

對象的

count

字段置0,表示掃描開始時,所有節(jié)點都是白色節(jié)點。

調用

scan_block

函數(shù)掃描

數(shù)據(jù)段

未初始化數(shù)據(jù)段,因為這兩個區(qū)域可能存在指針。

掃描所有

內存頁結構,這是因為內存頁結構可能會引用其他內存塊,所以也要對其進行掃描。

掃描所有

進程內核棧,由于進程內核棧可能存在指針,所以要對其進行掃描。

掃描所有

灰色節(jié)點,由于灰色節(jié)點也可能存在指針,所以要對其進行掃描。

掃描主要通過

scan_block

函數(shù)進行,我們來看看

scan_block

函數(shù)的實現(xiàn):

static

voidscan_block(void

*_start,

void

*_end,

struct

kmemleak_object

*scanned,

int

allow_resched){

unsigned

long

*ptr;

unsigned

long

*start

=

PTR_ALIGN(_start,

BY(TE)S_PER_POINTER);

unsigned

long

*end

=

_end

-

(BYTES_PER_POINTER

-

1);

//

對內存區(qū)進行掃描

for

(ptr

=

start;

ptr

count++;

//

判斷當前對象是否灰色節(jié)點,如果是將其添加到灰色節(jié)點鏈表中

if

(color_gray(object))

{

list_add_t(ai)l(

...

con(ti)nue;

}

...

}}

scan_block

函數(shù)主要完成以下幾個步驟:

遍歷內存區(qū)所有指針。

查找指針所引用的內存塊是否存在于紅黑樹中,如果不存在就跳過處理此對象。

如果

kmemleak_object

對象不是白色,說明已經有指針引用此內存塊,跳過處理此對象。

kmemleak_object

對象的

count

字段進行加一

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論