內存泄漏指你用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) 優化配置。