內存泄漏與內存溢出的區別

內存溢出:

    是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;好比申請了一個Integer,但給他存了long才能存下的數,那就是內存溢出。算法

內存泄漏:

    是指程序在申請內存後,沒法釋放已申請的內存空間,一次內存泄漏危害能夠忽略,但內存泄漏堆積後果很嚴重,不管多少內存早晚會被佔光。數據庫

 

內存溢出的緣由:

一、內存中加載的數據量過於龐大,如一次從數據庫中取出過多數據;服務器

二、集合類中有對對象的引用,使用完後未清空,使得JVM不能回收;函數

三、代碼中存在死循環或循環產生過多重複的對象實體;工具

四、使用的第三方軟件中的bug;測試

五、啓動參數內存值設定的太小。日誌

內存溢出的解決方案:

第一步,修改JVM啓動參數,直接增長內存。(-Xms,-Xmx參數必定不要忘記加。)對象

第二步,檢查錯誤日誌,查看「OutOfMemory」錯誤前是否有其它異常或錯誤。遞歸

第三步,對代碼進行走查和分析,找出可能發生內存溢出的位置。內存

重點排查如下幾點:
1.檢查對數據庫查詢中,是否有一次得到所有數據的查詢。通常來講,若是一次取十萬條記錄到內存,就可能引發內存溢出。這個問題比較隱蔽,在上線前,數據庫中數據較少,不容易出問題,上線後,數據庫中數據多了,一次查詢就有可能引發內存溢出。所以對於數據庫查詢儘可能採用分頁的方式查詢。

2.檢查代碼中是否有死循環或遞歸調用。

3.檢查是否有大循環重複產生新對象實體。

4.檢查對數據庫查詢中,是否有一次得到所有數據的查詢。通常來講,若是一次取十萬條記錄到內存,就可能引發內存溢出。這個問題比較隱蔽,在上線前,數據庫中數據較少,不容易出問題,上線後,數據庫中數據多了,一次查詢就有可能引發內存溢出。所以對於數據庫查詢儘可能採用分頁的方式查詢。

5.檢查List、MAP等集合對象是否有使用完後,未清除的問題。List、MAP等集合對象會始終存有對對象的引用,使得這些對象不能被GC回收。

第四步,使用內存查看工具動態查看內存使用狀況

 

以發生的方式分類,內存泄漏能夠分爲四類:

1. 常發性內存泄漏。發生內存泄漏的代碼會被屢次執行到,每次被執行的時候都會致使一塊內存泄漏。  2. 偶發性內存泄漏。發生內存泄漏的代碼只有在某些特定環境或操做過程下才會發生。常發性和偶發性是相對的。對於特定的環境,偶發性的也許就變成了常發性的。因此測試環境和測試方法對檢測內存泄漏相當重要。  3. 一次性內存泄漏。發生內存泄漏的代碼只會被執行一次,或者因爲算法上的缺陷,致使總會有一塊僅且一塊內存發生泄漏。好比,在類的構造函數中分配內存,在析構函數中卻沒有釋放該內存,因此內存泄漏只會發生一次。  4. 隱式內存泄漏。程序在運行過程當中不停的分配內存,可是直到結束的時候才釋放內存。嚴格的說這裏並無發生內存泄漏,由於最終程序釋放了全部申請的內存。可是對於一個服務器程序,須要運行幾天,幾周甚至幾個月,不及時釋放內存也可能致使最終耗盡系統的全部內存。因此,咱們稱這類內存泄漏爲隱式內存泄漏。  從用戶使用程序的角度來看,內存泄漏自己不會產生什麼危害,做爲通常的用戶,根本感受不到內存泄漏的存在。真正有危害的是內存泄漏的堆積,這會最終消耗盡系統全部的內存。從這個角度來講,一次性內存泄漏並無什麼危害,由於它不會堆積,而隱式內存泄漏危害性則很是大,由於較之於常發性和偶發性內存泄漏它更難被檢測到 

相關文章
相關標籤/搜索