linux中記憶體洩漏的檢測(一)最簡單的方法

懷想天空2015發表於2017-08-10

什麼是記憶體洩漏

記憶體洩漏是指程式動態申請的記憶體在使用完後沒有釋放,導致這段記憶體不能被作業系統回收再利用。 
例如這段程式,申請了4個位元組的空間但沒有釋放,有4個位元組的記憶體洩漏。

#include <iostream>
using namespace std;

int main()
{
     int *p = new int(1);
     cout <<*p<<endl;
     return 0
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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

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

記憶體洩漏特點

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

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

最簡單的方法

為了避免寫出記憶體洩漏的程式,通常會有這樣的程式設計規範,要求我們在寫程式時申請和釋放成對出現的。因為每一次申請都意味著必須有一次釋放與它相對應。

基於這個特點,一種簡單的方法就是在程式碼中統計申請和釋放的次數,如果申請和釋放的數量不同,就認為是記憶體洩漏了。

#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
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

方法分析

  • 優點:

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

  • 缺點:

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

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

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

4.對於所呼叫的庫不適用。如果希望應用於庫,則要修改庫程式碼

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

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

改進

這種方法雖然簡單的,卻有許多的不足,無法真正應用於專案中。欲知怎樣改進,且看下回分解。

相關文章