內(nèi)存泄漏指你用malloc或new申請了一塊內(nèi)存,但是沒有通過free或delete將內(nèi)存釋放,導(dǎo)致這塊內(nèi)存一直處于占用狀態(tài)。
內(nèi)存溢出指你申請了10個字節(jié)的空間,但是你在這個空間寫入11或以上字節(jié)的數(shù)據(jù),就是溢出。
內(nèi)存泄露是指程序中間動態(tài)分配了內(nèi)存,但在程序結(jié)束時沒有釋放這部分內(nèi)存,從而造成那部分內(nèi)存不可用的情況,重啟計算機(jī)可以解決,但也有可能再次發(fā)生內(nèi)存泄露,內(nèi)存泄露和硬件沒有關(guān)系,它是由軟件設(shè)計缺陷引起的。
內(nèi)存泄漏可以分為4類: 1)常發(fā)性內(nèi)存泄漏。發(fā)生內(nèi)存泄漏的代碼會被多次執(zhí)行到,每次被執(zhí)行的時候都會導(dǎo)致一塊內(nèi)存泄漏。
2)偶發(fā)性內(nèi)存泄漏。發(fā)生內(nèi)存泄漏的代碼只有在某些特定環(huán)境或操作過程下才會發(fā)生。常發(fā)性和偶發(fā)性是相對的。對于特定的環(huán)境,偶發(fā)性的也許就變成了常發(fā)性的。所以測試環(huán)境和測試方法對檢測內(nèi)存泄漏至關(guān)重要。
3)一次性內(nèi)存泄漏。發(fā)生內(nèi)存泄漏的代碼只會被執(zhí)行一次,或者由于算法上的缺陷,導(dǎo)致總會有一塊僅且一塊內(nèi)存發(fā)生泄漏。比如,在類的構(gòu)造函數(shù)中分配內(nèi)存,在析構(gòu)函數(shù)中卻沒有釋放該內(nèi)存,所以內(nèi)存泄漏只會發(fā)生一次。
4)隱式內(nèi)存泄漏。程序在運行過程中不停的分配內(nèi)存,但是直到結(jié)束的時候才釋放內(nèi)存。嚴(yán)格的說這里并沒有發(fā)生內(nèi)存泄漏,因為最終程序釋放了所有申請的內(nèi)存。但是對于一個服務(wù)器程序,需要運行幾天,幾周甚至幾個月,不及時釋放內(nèi)存也可能導(dǎo)致最終耗盡系統(tǒng)的所有內(nèi)存。所以,我們稱這類內(nèi)存泄漏為隱式內(nèi)存泄漏。
內(nèi)存溢出即用戶在對其數(shù)據(jù)緩沖區(qū)操作時,超過了其緩沖區(qū)的邊界;尤其是對緩沖區(qū)寫操作時,緩沖區(qū)的溢出很可能導(dǎo)致程序的異常。
java內(nèi)存泄露與溢出的區(qū)別
內(nèi)存溢出就是你要求分配的內(nèi)存超出了系統(tǒng)能給你的,系統(tǒng)不能滿足需求,于是產(chǎn)生溢出。
Java內(nèi)存泄漏就是沒有及時清理內(nèi)存垃圾,導(dǎo)致系統(tǒng)無法再給你提供內(nèi)存資源(內(nèi)存資源耗盡)。
看到上面的解釋,可能有些朋友還是不太理解吧。沒問題,看以下例子:
1.Java內(nèi)存泄露是說程序邏輯問題,造成申請的內(nèi)存無法釋放.這樣的話無論多少內(nèi)存,早晚都會被占用光的. 最簡單的例子就是死循環(huán)了.由于程序判斷錯誤導(dǎo)經(jīng)常發(fā)生此事。
2.Java內(nèi)存泄漏是指在堆上分配的內(nèi)存沒有被釋放,從而失去對其控制。這樣會造成程序能使用的內(nèi)存越來越少,導(dǎo)致系統(tǒng)運行速度減慢,嚴(yán)重情況會使程序當(dāng)?shù)簟?/p>
3.關(guān)于內(nèi)存溢出有點出入。比如說你申請了一個integer,但給它存了long才能存下的數(shù),那就是內(nèi)存溢出。
舉個現(xiàn)實中的例子: 比如有一個桶,裝滿了水.你丟個蘋果進(jìn)去。桶的水正常。如果你放個大石頭。水就出溢出,內(nèi)存溢出也就是這個原理。 區(qū)別:內(nèi)存溢出,提供的內(nèi)存不夠;Java內(nèi)存泄漏,無法再提供內(nèi)存資源。
相關(guān)問題
Q:Java中會存在內(nèi)存泄漏嗎? A: Java中也存在內(nèi)存泄露。當(dāng)被分配的對象可達(dá)但已無用(未對作廢數(shù)據(jù)內(nèi)存單元的引用置null)即會引起。
Q: 如何避免內(nèi)存泄露、溢出? A: 1)盡早釋放無用對象的引用。
好的辦法是使用臨時變量的時候,讓引用變量在退出活動域后自動設(shè)置為null,暗示垃圾收集器來收集該對象,防止發(fā)生內(nèi)存泄露。
2)程序進(jìn)行字符串處理時,盡量避免使用String,而應(yīng)使用StringBuffer。
3) 盡量少用靜態(tài)變量。
因為靜態(tài)變量是全局的,GC不會回收。
4)避免集中創(chuàng)建對象尤其是大對象,如果可以的話盡量使用流操作。
5)盡量運用對象池技術(shù)以提高系統(tǒng)性能。
生命周期長的對象擁有生命周期短的對象時容易引發(fā)內(nèi)存泄漏,例如大集合對象擁有大數(shù)據(jù)量的業(yè)務(wù)對象的時候,可以考慮分塊進(jìn)行處理,然后解決一塊釋放一塊的策略。
6)不要在經(jīng)常調(diào)用的方法中創(chuàng)建對象,尤其是忌諱在循環(huán)中創(chuàng)建對象。
可以適當(dāng)?shù)氖褂胔ashtable,vector創(chuàng)建一組對象容器,然后從容器中去取那些對象,而不用每次new之后又丟棄。
7) 優(yōu)化配置。
新聞熱點
疑難解答