Java 內存泄漏與內存溢出詳解

內存泄漏指你用malloc或new申請了一塊內存,但是沒有通過free或delete將內存釋放,導致這塊內存一直處於佔用狀態。

內存溢出指你申請了10個字節的空間,但是你在這個空間寫入11或以上字節的數據,就是溢出。


內存泄露是指程序中間動態分配了內存,但在程序結束時沒有釋放這部分內存,從而造成那部分內存不可用的情況,重啓計算機可以解決,但也有可能再次發生內存泄露,內存泄露和硬件沒有關係,它是由軟件設計缺陷引起的。

內存泄漏可以分爲4類:
1)常發性內存泄漏。發生內存泄漏的代碼會被多次執行到,每次被執行的時候都會導致一塊內存泄漏。

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

3)一次性內存泄漏。發生內存泄漏的代碼只會被執行一次,或者由於算法上的缺陷,導致總會有一塊僅且一塊內存發生泄漏。比如,在類的構造函數中分配內存,在析構函數中卻沒有釋放該內存,所以內存泄漏只會發生一次。

4)隱式內存泄漏。程序在運行過程中不停的分配內存,但是直到結束的時候才釋放內存。嚴格的說這裏並沒有發生內存泄漏,因爲最終程序釋放了所有申請的內存。但是對於一個服務器程序,需要運行幾天,幾周甚至幾個月,不及時釋放內存也可能導致最終耗盡系統的所有內存。所以,我們稱這類內存泄漏爲隱式內存泄漏。

內存溢出即用戶在對其數據緩衝區操作時,超過了其緩衝區的邊界;尤其是對緩衝區寫操作時,緩衝區的溢出很可能導致程序的異常。


Java內存泄露與溢出的區別

內存溢出就是你要求分配的內存超出了系統能給你的,系統不能滿足需求,於是產生溢出。

Java內存泄漏就是沒有及時清理內存垃圾,導致系統無法再給你提供內存資源(內存資源耗盡)。

看到上面的解釋,可能有些朋友還是不太理解吧。沒問題,看以下例子:

1.Java內存泄露是說程序邏輯問題,造成申請的內存無法釋放.這樣的話無論多少內存,早晚都會被佔用光的.
最簡單的例子就是死循環了.由於程序判斷錯誤導經常發生此事。

2.Java內存泄漏是指在堆上分配的內存沒有被釋放,從而失去對其控制。這樣會造成程序能使用的內存越來越少,導致系統運行速度減慢,嚴重情況會使程序當掉。

3.關於內存溢出有點出入。比如說你申請了一個integer,但給它存了long才能存下的數,那就是內存溢出。

舉個現實中的例子:
比如有一個桶,裝滿了水.你丟個蘋果進去。桶的水正常。如果你放個大石頭。水就出溢出,內存溢出也就是這個原理。
區別:內存溢出,提供的內存不夠;Java內存泄漏,無法再提供內存資源。


相關問題

Q:Java中會存在內存泄漏嗎?
A: Java中也存在內存泄露。當被分配的對象可達但已無用(未對作廢數據內存單元的引用置null)即會引起。

Q: 如何避免內存泄露、溢出?
A: 1)儘早釋放無用對象的引用。

好的辦法是使用臨時變量的時候,讓引用變量在退出活動域後自動設置爲null,暗示垃圾收集器來收集該對象,防止發生內存泄露。

2)程序進行字符串處理時,儘量避免使用String,而應使用StringBuffer。

3) 儘量少用靜態變量。

因爲靜態變量是全局的,GC不會回收。

4)避免集中創建對象尤其是大對象,如果可以的話儘量使用流操作。

5)儘量運用對象池技術以提高系統性能。

生命週期長的對象擁有生命週期短的對象時容易引發內存泄漏,例如大集合對象擁有大數據量的業務對象的時候,可以考慮分塊進行處理,然後解決一塊釋放一塊的策略。

6)不要在經常調用的方法中創建對象,尤其是忌諱在循環中創建對象。

可以適當的使用hashtable,vector創建一組對象容器,然後從容器中去取那些對象,而不用每次new之後又丟棄。

7) 優化配置。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章