造成內存泄露的原因
造成內存泄露的原因
內存泄漏一般是指程序中己動態(tài)分配的堆內存由于某種原因程序未釋放或無法釋放,造成系統(tǒng)內存的浪費。下面學習啦給大家分析造成內存泄露的原因。
造成內存泄露的原因
嚴格意義上的內存泄露的原因只有一種:沒有釋放向系統(tǒng)申請的內存,因為不申請內存,就談不上什么泄露,搞清楚內存泄露的原因,應當從匯編語言的角度考慮問題。 當然沒有釋放內存的原因是多種的: 有可能是你自己代碼寫的不好,忘記了釋放自己代碼里申請的內存, 也有可能是你使用了一個寫的不好的庫,庫本身有問題,這里說的庫不僅僅是第三方庫,甚至于各種語言的運行時庫也有可能出現(xiàn)(再高的人都免不了出BUG),還甚至于操作系統(tǒng)的庫,因為操作系統(tǒng)的BUG也多的很(當然系統(tǒng)一般情況不會出現(xiàn)這些低級的錯誤)。 死循環(huán)不能說是內存泄露,概念上應稱為死鎖,死鎖的確是有可能會導致內存無限量增長,但其與內存泄露有本質區(qū)別,盡管有時候它們導致的結果在內存層面是相同的。
泄漏的分類
以發(fā)生的方式來分類,內存泄漏可以分為4類:
(1). 常發(fā)性內存泄漏?!“l(fā)生內存泄漏的代碼會被多次執(zhí)行到,每次被執(zhí)行的時候都會導致一塊內存泄漏。
(2). 偶發(fā)性內存泄漏?!“l(fā)生內存泄漏的代碼只有在某些特定環(huán)境或操作過程下才會發(fā)生。常發(fā)性和偶發(fā)性是相對的。對于特定的環(huán)境,偶發(fā)性的也許就變成了常發(fā)性的。所以測試環(huán)境和測試方法對檢測內存泄漏至關重要。
(3). 一次性內存泄漏?!“l(fā)生內存泄漏的代碼只會被執(zhí)行一次,或者由于算法上的缺陷,導致總會有一塊僅且一塊內存發(fā)生泄漏。比如,在類的構造函數(shù)中分配內存,在析構函數(shù)中卻沒有釋放該內存,所以內存泄漏只會發(fā)生一次。
(4). 隱式內存泄漏?! 〕绦蛟谶\行過程中不停的分配內存,但是直到結束的時候才釋放內存。嚴格的說這里并沒有發(fā)生內存泄漏,因為最終程序釋放了所有申請的內存。但是對于一個服務器程序,需要運行幾天,幾周甚至幾個月,不及時釋放內存也可能導致最終耗盡系統(tǒng)的所有內存。所以,我們稱這類內存泄漏為隱式內存泄漏。
編輯本段危害 從用戶使用程序的角度來看,內存泄漏本身不會產(chǎn)生什么危害,作為一般的用戶,根本感覺不到內存泄漏的存在。真正有危害的是內存泄漏的堆積,這會最終消耗盡系統(tǒng)所有的內存。從這個角度來說,一次性內存泄漏并沒有什么危害,因為它不會堆積,而隱式內存泄漏危害性則非常大,因為較之于常發(fā)性和偶發(fā)性內存泄漏它更難被檢測到。
內存泄漏的表現(xiàn)
內存泄漏或者是說,資源耗盡后,系統(tǒng)會表現(xiàn)出什么現(xiàn)象哪?
cpu資源耗盡:估計是機器沒有反應了,鍵盤,鼠標,以及網(wǎng)絡等等。這個在windows上經(jīng)??匆?,特別是中了毒。
進程id耗盡:沒法創(chuàng)建新的進程了,串口或者telnet都沒法創(chuàng)建了。
硬盤耗盡: 機器要死了,交換內存沒法用,日志也沒法用了,死是很正常的。
內存泄漏或者內存耗盡:新的連接無法創(chuàng)建,free的內存比較少。發(fā)生內存泄漏的程序很多,但是要想產(chǎn)生一定的后果,就需要這個進程是無限循環(huán)的,是個服務進程。當然,內核也是無限循環(huán)的,所以,如果內核發(fā)生了內存泄漏,情況就更加不妙。內存泄漏是一種很難定位和跟蹤的錯誤,目前還沒看到有什么好用的工具(當然,用戶空間有一些工具,有靜態(tài)分析的,也會動態(tài)分析的,但是找內核的內存泄漏,沒有好的開源工具)
內存泄漏和對象的引用計數(shù)有很大的關系,再加上c/c++都沒有自動的垃圾回收機制,如果沒有手動釋放內存,問題就會出現(xiàn)。如果要避免這個問題,還是要從代碼上入手,良好的編碼習慣和規(guī)范,是避免錯誤的不二法門。
一般我們常說的內存泄漏是指堆內存的泄漏。
堆內存是指程序從堆中分配的,大小任意的(內存塊的大小可以在程序運行期決定),使用完后必須顯示釋放的內存。
應用程序一般使用malloc,realloc,new等函數(shù)從堆中分配到一塊內存,使用完后,程序必須負責相應的調用free或delete釋放該內存塊,否則,這塊內存就不能被再次使用,我們就說這塊內存泄漏了。
內存泄露的危害
從用戶使用程序的角度來看,內存泄漏本身不會產(chǎn)生什么危害,作為一般的用戶,根本感覺不到內存泄漏的存在。真正有危害的是內存泄漏的堆積,這會最終消耗盡系統(tǒng)所有的內存。從這個角度來說,一次性內存泄漏并沒有什么危害,因為它不會堆積,而隱式內存泄漏危害性則非常大,因為較之于常發(fā)性和偶發(fā)性內存泄漏它更難被檢測到。
檢查內存的工具
1.ccmalloc-Linux和Solaris下對C和C++程序的簡單的使用內存泄漏和malloc調試庫。
2.Dmalloc-Debug Malloc Library.
3.Electric Fence-Linux分發(fā)版中由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-幫助開發(fā)人員查明C/C++、托管.NET、Java和VB6代碼中的性能和可靠性錯誤。PurifyPlus 將內存錯誤和泄漏檢測、應用程序性能描述、代碼覆蓋分析等功能組合在一個單一、完整的工具包中。
10.ParasoftInsure++-針對C/C++應用的運行時錯誤自動檢測工具,它能夠自動監(jiān)測C/C++程序,發(fā)現(xiàn)其中存在著的內存破壞、內存泄漏、指針錯誤和I/O等錯誤。并通過使用一系列獨特的技術(SCI技術和變異測試等),徹底的檢查和測試我們的代碼,精確定位錯誤的準確位置并給出詳細的診斷信息。能作為MicrosoftVisual C++的一個插件運行。
11.Compuware DevPartner for Visual C++ BoundsChecker Suite-為C++開發(fā)者設計的運行錯誤檢測和調試工具軟件。作為Microsoft Visual Studio和C++ 6.0的一個插件運行。
12.Electric Software GlowCode-包括內存泄漏檢查,code profiler,函數(shù)調用跟蹤等功能。給C++和.Net開發(fā)者提供完整的錯誤診斷,和運行時性能分析工具包。
猜你感興趣:
3.c內存泄露的原因