malloc_stats---檢查記憶體洩露的神器

pamxy發表於2013-06-20

轉自:http://m.blog.csdn.net/blog/hust_wusen/8781680

在之前的部落格中提到過,valgrind可以用來檢測記憶體洩露,但在使用中,往往會遇到一些問題,給除錯工作帶來很多不必要的麻煩,我自己遇到的有以下兩種:

      (1)記憶體洩露誤檢(系統初始化時,可能有一些需要長期儲存在記憶體中的資料結構,這些空間是永遠不釋放的,而這些記憶體會被認為絕對洩露)

      (2) valgrind檢查記憶體洩露過於全面,執行後的結果太多往往很難從中找到有用的資訊。有時候,我們只需要關注某些函式,可能在執行某個操作,呼叫某些函式時會出現記憶體洩露,此時,valgrind的工作顯得冗餘而複雜

系統庫函式中提供了malloc_stats()函式,可以統計本程式具體的記憶體使用情況,精確到位元組,malloc_stats()函式宣告如下:

#include<stdlib.h>

void malloc_stats(void);

malloc_stats()執行結果如下:

Arena 0://第一個arena(每個執行緒分配一個arena),這裡只有一個執行緒
system bytes     =     135168//本執行緒從作業系統獲得的動態記憶體,這裡是132KB
in use bytes     =       1152//本執行緒在使用的動態記憶體,1152位元組
Total (incl. mmap)://總的使用情況,各個執行緒使用動態記憶體的累加值
system bytes     =     135168//本程式從作業系統獲得的動態記憶體,這裡是132KB
in use bytes     =       1152//本程式在使用的動態記憶體,1152位元組
max mmap regions =          0//當一次申請記憶體超過128KB(32位作業系統)或1MB(64位作業系統)時,會增加mmap區域,這裡統計使用mmap區域的個數
max mmap bytes   =          0//mmap區域對應記憶體大小

不說廢話,來段程式碼看看效果

//test_malloc_stats.c
#include<stdio.h>
#include<stdlib.h>

int func1();

int main()
{
	char *p=NULL;
	p=(char *)malloc(100);
	if(!p){
		printf("In main ,malloc fail\n");
		return -1;
	}
	printf("********before call func1 **********\n");
	malloc_stats();//在要執行記憶體檢測的函式之前列印記憶體資訊
	
	func1();
	printf("\n@@@@@@@@after call func1 @@@@@@@@@@@\n");
	malloc_stats();//在要執行記憶體檢測的函式之後列印記憶體資訊
	free(p);
	return 1;
	
}

int func1(void)//申請1024位元組,但沒有釋放,有記憶體洩露
{
	char *p=NULL;
	p=(char *)malloc(1024);//func1函式申請1024位元組
	if(!p)
	{
		printf("Malloc error\n");
	}
	return 0;
}
如上程式碼,編譯(gcc test_malloc_stats.c ),執行(./a.out),結果如下


如上圖,在呼叫func1之前,記憶體使用位112B,呼叫之後,記憶體使用1152B,增加了1040位元組,說明函式func1存在記憶體洩露,此時檢查func1函式程式碼即可。如果func1確實會造成1040B的記憶體使用,這就說明func1沒有問題。


這裡,您可能會發現申請了1024位元組,實際記憶體佔用1040位元組,這正是glib庫的實現,另外的16位元組用來管理分配的資料塊

 

相關文章