當前位置:才華齋>計算機>C語言>

C語言中的記憶體怎樣避免與檢測與洩露

C語言 閱讀(2.9W)

有些程式並不需要管理它們的動態記憶體的使用。當需要記憶體時,它們簡單地通過分配來獲得,從來不用擔心如何釋放它。這類程式包括編譯器和其他一些執行一段固定的(或有限的)時間然後終止的程式。當這種型別的程式終止時,所有記憶體會被自動回收。細心查驗每塊記憶體是否需要回收純屬浪費時間,因為它們不會再被使用。

C語言中的記憶體怎樣避免與檢測與洩露

其他程式的生存時間要長一點。有些工具如日曆管理器、郵件工具以及作業系統本事經常需要數日及至數週連續執行,並需要管理動態記憶體的分配和回收。由於C語言通常並不使用垃圾回收器(自動確認並回收不再使用的記憶體塊),這些C程式在使用malloc()和free()時不得不非常慎重。

堆經常會出現兩種型別的問題:

1.釋放或改寫仍在使用的記憶體(稱為:“記憶體損壞”)。

2.未釋放不再使用的記憶體(稱為:“記憶體洩露”)。

這是最難被除錯發現的問題之一。如果每次已分配的記憶體塊不再使用而程式並不釋放它們,程序就會一邊分配越來越多的記憶體,一邊卻並不釋放不再使用的那部分記憶體。

避免記憶體洩露

每當呼叫malloc分配記憶體時,注意在以後要呼叫相應的free來釋放它。

如果不知道如何呼叫free與先前的malloc相對應,那麼很可能已經造成了記憶體洩露!

一種簡單的方法就是在可能的時候使用alloca()來分配動態記憶體,以避免上述情況。當離開呼叫alloca的函式時,它所分配的記憶體會被自動釋放。

顯然,這並不適用於那些比建立它們的函式生命期更長的結構。但如果物件的生命期在該函式結束前便已經終止,這種建立在堆疊上的動態記憶體分配是一種開銷很小的選擇。有些人不提倡使用alloca,因為它並不是以後總可移植的方法。如果處理器在硬體上不支援堆疊,alloca()就很難高效地實現。

我們使用“記憶體洩露”這個詞是因為一種稀有的資源正在被一個程序榨乾。記憶體洩露的主要可見症狀就是罪魁程序的速度很減慢。原因是體積大的程序更有可能被系統換出,讓別的程序執行,而且大的程序在換進換出時花費的時間也更多。即使洩露的`記憶體本省並不被引用,但它仍用可能存在於頁面中(內容自然是垃圾),這樣就增加了程序的工作頁數量,降低了效能。另外需要注意的一點是,記憶體洩露往往比忘記釋放的的資料結構要打,因為malloc()所分配的記憶體通常會圓整為下一個大於申請數量的2的整數次方(如申請212B,會圓整為256B)。在資源有限的情況下,即使引起記憶體洩露的程序並不執行,整個系統執行速度也會被拖慢。從理論上說,程序的大小有一個上限值,這在不同的作業系統中各不相同。在當前的SunOS版本中,程序的最大地址空間可以多達4GB。事實上,在程序所洩露的記憶體遠未達到這個數量時,磁碟的交換區早已消耗殆盡。

如何檢測記憶體洩露

觀察記憶體洩露是一個兩步驟的過程。首先,使用swap命令觀察還有多少可用的交換空間:

/usr/sbin/swap -s

total:17228K bytes allocated + 5396K reserved=22626K used,29548K available.

在一兩分鐘內鍵入該命令三到四次,看看可用的交換區是否在減少。還可以使用其他一些/usr/bin/*stat工具如netstat、vmstat等。如發現波段有記憶體被分配且從不釋放,一個可能的解釋就是有個程序出現了記憶體洩露。