JVM記憶體洩漏與溢位以及解決方案

2021-10-10 10:45:14 字數 1145 閱讀 7287

簡單地說就是申請了一塊記憶體空間,使用完畢後沒有釋放掉。它的一般表現方式是程式執行時間越長,占用記憶體越多,最終用盡全部記憶體,整個系統崩潰。由程式申請的一塊記憶體,且沒有任何乙個指標指向它,那麼這塊記憶體就洩露了。

記憶體洩漏是造成應用程式oom的主要原因之一。我們知道android系統為每個應用程式分配的記憶體是有限的,而當乙個應用中產生的記憶體洩漏比較多時,這就難免會導致應用所需要的記憶體超過系統分配的記憶體限額,這就造成了記憶體溢位從而導致應用crash。

因為記憶體洩漏是在堆記憶體中,所以對我們來說並不是可見的。通常我們可以借助mat、leakcanary等工具來檢測應用程式是否存在記憶體洩漏。

1、mat是一款強大的記憶體分析工具,功能繁多而複雜。

2、leakcanary則是由square開源的一款輕量級的第三方記憶體洩漏檢測工具,當檢測到程式中產生記憶體洩漏時,它將以最直觀的方式告訴我們**產生了記憶體洩漏和導致誰洩漏了而不能被**。

記憶體溢位是指應用系統中存在無法**的記憶體或使用的記憶體過多,最終使得程式執行要用到的記憶體大於虛擬機器能提供的最大記憶體。

引起記憶體溢位的原因有很多種,常見的有以下幾種:

記憶體中載入的資料量過於龐大,如一次從資料庫取出過多資料;

集合類中有對物件的引用,使用完後未清空,使得jvm不能**。

**中存在死迴圈或迴圈產生過多重複的物件實體。

使用的第三方軟體中的bug。

啟動引數記憶體值設定的過小。

記憶體溢位的解決方案:

重點排查以下幾點:

檢查對資料庫查詢中,是否有一次獲得全部資料的查詢。

一般來說,如果一次取十萬條記錄到記憶體,就可能引起記憶體溢位。這個問題比較隱蔽,在上線前,資料庫中資料較少,不容易出問題,上線後,資料庫中資料多了,一次查詢就有可能引起記憶體溢位。因此對於資料庫查詢盡量採用分頁的方式查詢。

檢查**中是否有死迴圈或遞迴呼叫。

檢查是否有大迴圈重複產生新物件實體。

檢查對資料庫查詢中,是否有一次獲得全部資料的查詢。一般來說,如果一次取十萬條記錄到記憶體,就可能引起記憶體溢位。這個問題比較隱蔽,在上線前,資料庫中資料較少,不容易出問題,上線後,資料庫中資料多了,一次查詢就有可能引起記憶體溢位。因此對於資料庫查詢盡量採用分頁的方式查詢。

檢查list、map等集合物件是否有使用完後,未清除的問題。list、map等集合物件會始終存有對物件的引用,使得這些物件不能被gc**。

JVM記憶體洩漏和記憶體溢位

相同與不同 如何避免記憶體洩漏 我們用棧來模擬,首先我們定義乙個我們自己的棧,如下圖所示 package com.zhuguang.allen public class stack 入棧 public void push object e 出棧 public object pop 假如沒有在出棧的時...

記憶體洩漏與溢位

記憶體溢位 out of memory,是指程式在申請記憶體時,沒有足夠的記憶體空間供其使用,出現out of memory 比如申請了乙個integer,但給它存了long才能存下的數,那就是記憶體溢位。記憶體洩露 memory leak,是指程式在申請記憶體後,無法釋放已申請的記憶體空間,一次記...

記憶體洩漏與記憶體溢位

概念 記憶體溢位指的是我們的程式在申請的記憶體時,沒有足夠的記憶體空間供其使用。記憶體洩漏指的是我們占用了某塊記憶體,而又不再使用它,長期堆積的記憶體洩漏也將導致記憶體溢位。舉例 當我們去自助餐吃牛排的時候,本來乙個盤子只能裝幾片西瓜,結果我們裝了十多片導致西瓜掉出來了,這就是記憶體上溢,這是從小的...