內存泄露與內存溢出傻傻分不清?幫你簡單理清楚!

內存泄露與內存溢出都會導致內存無法得到合理的使用,只是之間確實有些差異,容易混淆。

簡單來說,內存泄露是不需要存活的對象無法被回收佔用內存。內存溢出是必要的對象沒有足夠的內存來創建。

內存泄露

內存泄漏(memory leak ):是指程序在申請內存後,無法釋放已申請的內存空間就造成了內存泄漏,一次內存泄漏似乎不會有大的影響,但內存泄漏堆積後的後果就是內存溢出。

常見原因

當一個對象已經不需要再使用本該被回收時,另外一個正在使用的對象持有它的引用從而導致它不能被回收,這導致本該被回收的對象不能被回收而停留在堆內存中,這就產生了內存泄漏。

我的理解就是,因爲編碼問題,導致生命週期很短且本該回收的對象一直無法被gc。

舉個例子

靜態類實現單例模式。因爲其生命週期和應用的生命週期一樣長,所以如果在創建單例時,傳入了其他對象,則該對象將一直無法被回收。

/**
 * 靜態類實現單例模式,如果傳入對象,則當前對象生命週期將與應用生命週期一致
 *
 * @author baijiaan
 * @date 2020-05-27
 */
public class SingleInstanceTest {

    private static SingleInstanceTest sInstance;
    private OneObject oneObject;

    private SingleInstanceTest(OneObject oneObject) {
        this.oneObject = oneObject;
    }

    public static SingleInstanceTest newInstance(OneObject oneObject) {
        if (sInstance == null) {
            sInstance = new SingleInstanceTest(oneObject);
        }
        return sInstance;
    }
}

內存溢出

內存溢出(out of memory): 指程序申請內存時,沒有足夠的內存供申請者使用,或者說,給了你一塊存儲int類型數據的存儲空間,但是你卻存儲long類型的數據,那麼結果就是內存不夠用,此時就會報錯OOM,即所謂的內存溢出,簡單來說就是自己所需要使用的空間比我們擁有的內存大,內存不夠使用所造成的內存溢出。

常見原因

內存溢出的原因比較寬泛:

  1. 可能是分配的內存本身就不夠
  2. 一次性裝載到內存的數據量過大
  3. 內存泄露使內存被不合理的佔用導致可用內存不夠
  4. 編碼問題,比如進入了一個循環創建對象的情況

解決方法

對應上面的常見原因,我們大概的解決思路是:

  1. 修改-Xmx
  2. 防止一次性加載過多數據
  3. 找OutOfMemory異常來定位問題出現位置
  4. 養成良好的編碼習慣

總結

個人理解,內存泄露是一種行爲,而內存溢出是一個結果。內存溢出這個結果出現了,那系統就不能正常使用了。而偶爾的內存泄露不可怕,頻繁的內存泄露可能會造成惡劣的後果。

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