大家都知道,在堆上分配的記憶體,如果不再使用了,就應該及時釋放,以便後面其他地方可以重用。而在 C 語言中,記憶體管理器不會自動回收不再使用的記憶體。如果忘了釋放不再使用的記憶體,這些記憶體就不能被重用了,這就造成了
記憶體漏失。
記憶體漏失幾乎是很難避免的,不管是老手還是新手,都存在這個問題,甚至 Windows 與 Linux 這類系統軟體也或多或少存在著記憶體漏失。
也許對一般的應用軟體來說,這個問題似乎不是那麼突出與嚴重。一兩處記憶體漏失通常並不致於讓程式崩潰,也不會帶來邏輯上的錯誤,而且在進程退出時,系統會自動釋放所有與該進程相關的記憶體(共用記憶體除外),所以記憶體漏失的後果相對來說還是比較溫和的。但是,量變會導致質變,一旦記憶體漏失過多以致耗盡記憶體,後續記憶體分配將會失敗,程式就可能因此而崩潰。
在常見情況下,記憶體漏失的主要可見症狀就是罪魁進程的速度減慢。原因是體積大的進程更有可能被系統換出,讓別的進程執行,而且大的進程在換進換出時花費的時間也更多。即使洩漏的記憶體本身並不被參照,但它仍然可能存在於頁面中(內容自然是垃圾),這樣就增加了進程的工作頁數量,降低了效能。
下面展示了一些導致記憶體漏失的常見場景。
1) 指標重新賦值
看下面一段範例程式碼:
char * p = (char *)malloc(10);
char * np = (char *)malloc(10);
其中,指標變數 p 和 np 分別被分配了 10 個位元組的記憶體,它們各自的記憶體如圖 1 所示。
圖 1 p 和 np 賦值前的記憶體