造成記憶體洩露的原因

  記憶體洩漏一般是指程式中己動態分配的堆記憶體由於某種原因程式未釋放或無法釋放,造成系統記憶體的浪費。下面給大家分析。

  

  嚴格意義上的記憶體洩露的原因只有一種:沒有釋放向系統申請的記憶體,因為不申請記憶體,就談不上什麼洩露,搞清楚記憶體洩露的原因,應當從組合語言的角度考慮問題。 當然沒有釋放記憶體的原因是多種的: 有可能是你自己程式碼寫的不好,忘記了釋放自己程式碼裡申請的記憶體, 也有可能是你使用了一個寫的不好的庫,庫本身有問題,這裡說的庫不僅僅是第三方庫,甚至於各種語言的執行時庫也有可能出現***再高的人都免不了出BUG***,還甚至於作業系統的庫,因為作業系統的BUG也多的很***當然系統一般情況不會出現這些低階的錯誤***。 死迴圈不能說是記憶體洩露,概念上應稱為死鎖,死鎖的確是有可能會導致記憶體無限量增長,但其與記憶體洩露有本質區別,儘管有時候它們導致的結果在記憶體層面是相同的。

  洩漏的分類

  以發生的方式來分類,記憶體洩漏可以分為4類:

  ***1***. 常發性記憶體洩漏。 發生記憶體洩漏的程式碼會被多次執行到,每次被執行的時候都會導致一塊記憶體洩漏。

  ***2***. 偶發性記憶體洩漏。 發生記憶體洩漏的程式碼只有在某些特定環境或操作過程下才會發生。常發性和偶發性是相對的。對於特定的環境,偶發性的也許就變成了常發性的。所以測試環境和測試方法對檢測記憶體洩漏至關重要。

  ***3***. 一次性記憶體洩漏。 發生記憶體洩漏的程式碼只會被執行一次,或者由於演算法上的缺陷,導致總會有一塊僅且一塊記憶體發生洩漏。比如,在類的建構函式中分配記憶體,在解構函式中卻沒有釋放該記憶體,所以記憶體洩漏只會發生一次。

  ***4***. 隱式記憶體洩漏。  程式在執行過程中不停的分配記憶體,但是直到結束的時候才釋放記憶體。嚴格的說這裡並沒有發生記憶體洩漏,因為最終程式釋放了所有申請的記憶體。但是對於一個伺服器程式,需要執行幾天,幾周甚至幾個月,不及時釋放記憶體也可能導致最終耗盡系統的所有記憶體。所以,我們稱這類記憶體洩漏為隱式記憶體洩漏。

  編輯本段危害  從使用者使用程式的角度來看,記憶體洩漏本身不會產生什麼危害,作為一般的使用者,根本感覺不到記憶體洩漏的存在。真正有危害的是記憶體洩漏的堆積,這會最終消耗盡系統所有的記憶體。從這個角度來說,一次性記憶體洩漏並沒有什麼危害,因為它不會堆積,而隱式記憶體洩漏危害性則非常大,因為較之於常發性和偶發性記憶體洩漏它更難被檢測到。

  記憶體洩漏的表現

  記憶體洩漏或者是說,資源耗盡後,系統會表現出什麼現象哪?

  cpu資源耗盡:估計是機器沒有反應了,鍵盤,滑鼠,以及網路等等。這個在windows上經常看見,特別是中了毒。

  程序id耗盡:沒法建立新的程序了,串列埠或者telnet都沒法建立了。

  硬碟耗盡: 機器要死了,交換記憶體沒法用,日誌也沒法用了,死是很正常的。

  記憶體洩漏或者記憶體耗盡:新的連線無法建立,free的記憶體比較少。發生記憶體洩漏的程式很多,但是要想產生一定的後果,就需要這個程序是無限迴圈的,是個服務程序。當然,核心也是無限迴圈的,所以,如果核心發生了記憶體洩漏,情況就更加不妙。記憶體洩漏是一種很難定位和跟蹤的錯誤,目前還沒看到有什麼好用的工具***當然,使用者空間有一些工具,有靜態分析的,也會動態分析的,但是找核心的記憶體洩漏,沒有好的開源工具***

  記憶體洩漏和物件的引用計數有很大的關係,再加上c/c++都沒有自動的垃圾回收機制,如果沒有手動釋放記憶體,問題就會出現。如果要避免這個問題,還是要從程式碼上入手,良好的編碼習慣和規範,是避免錯誤的不二法門。

  一般我們常說的記憶體洩漏是指堆記憶體的洩漏。

  堆記憶體是指程式從堆中分配的,大小任意的***記憶體塊的大小可以在程式執行期決定***,使用完後必須顯示釋放的記憶體。

  應用程式一般使用malloc,realloc,new等函式從堆中分配到一塊記憶體,使用完後,程式必須負責相應的呼叫free或delete釋放該記憶體塊,否則,這塊記憶體就不能被再次使用,我們就說這塊記憶體洩漏了。

  記憶體洩露的危害

  從使用者使用程式的角度來看,記憶體洩漏本身不會產生什麼危害,作為一般的使用者,根本感覺不到記憶體洩漏的存在。真正有危害的是記憶體洩漏的堆積,這會最終消耗盡系統所有的記憶體。從這個角度來說,一次性記憶體洩漏並沒有什麼危害,因為它不會堆積,而隱式記憶體洩漏危害性則非常大,因為較之於常發性和偶發性記憶體洩漏它更難被檢測到。

  檢查記憶體的工具

  1.ccmalloc-Linux和Solaris下對C和C++程式的簡單的使用記憶體洩漏和malloc除錯庫。

  2.Dmalloc-Debug Malloc Library.

  3.Electric Fence-Linux分發版中由Bruce Perens編寫的malloc******除錯庫。

  4.Leaky-Linux下檢測記憶體洩漏的程式。

  5.LeakTracer-Linux、Solaris和HP-UX下跟蹤和分析C++程式中的記憶體洩漏。

  6.MEMWATCH-由Johan Lindh編寫,是一個開放原始碼C語言記憶體錯誤檢測工具,主要是通過gcc的precessor來進行。

  7.Valgrind-Debugging and profiling Linux programs, aiming at programs written in C and C++.

  8.KCachegrind-A visualization tool for the profiling data generated by Cachegrind and Calltree.

  9.IBM Rational PurifyPlus-幫助開發人員查明C/C++、託管.NET、Java和VB6程式碼中的效能和可靠性錯誤。PurifyPlus 將記憶體錯誤和洩漏檢測、應用程式效能描述、程式碼覆蓋分析等功能組合在一個單一、完整的工具包中。

  10.ParasoftInsure++-針對C/C++應用的執行時錯誤自動檢測工具,它能夠自動監測C/C++程式,發現其中存在著的記憶體破壞、記憶體洩漏、指標錯誤和I/O等錯誤。並通過使用一系列獨特的技術***SCI技術和變異測試等***,徹底的檢查和測試我們的程式碼,精確定位錯誤的準確位置並給出詳細的診斷資訊。能作為MicrosoftVisual C++的一個外掛執行。

  11.Compuware DevPartner for Visual C++ BoundsChecker Suite-為C++開發者設計的執行錯誤檢測和除錯工具軟體。作為Microsoft Visual Studio和C++ 6.0的一個外掛執行。

  12.Electric Software GlowCode-包括記憶體洩漏檢查,code profiler,函式呼叫跟蹤等功能。給C++和.Net開發者提供完整的錯誤診斷,和執行時效能分析工具包。