1、概念與區別算法
內存溢出
out of memory,是指程序在申請內存時,沒有足夠的內存空間供其使用,出現out of memory;好比申請 了一個integer,但給它存了long才能存下的數,那就是
內存溢出
內存泄露
memory leak,是指程序在申請內存後,沒法釋放已申請的內存空間,一次
內存泄露
危害能夠忽略,但
內存泄露
堆積後果很嚴重,不管多少內存,早晚會被佔光。 memory leak會最終會致使out of memory!
內存溢出
就是你要求分配的內存超出了系統能給你的,系統不能知足需求,因而產生溢出。 2、內存泄露
內存泄漏
是指你向系統申請
分配內存
進行使用(new),但是使用完了之後卻不歸還(delete),結果你申請到的那塊內 存你本身也不能再訪問(也許你把它的地址給弄丟了),而系統也不能再次將它分配給須要的程序。一個 盤子用盡各類方法只能裝4個果子,你裝了5個,結果掉倒地上不能吃了。這就是溢出!比方說棧,棧滿時 再作進棧一定產生空間溢出,叫上溢,棧空時再作退棧也產生空間溢出,稱爲下溢。就是分配的內存不足 以放下
數據項
序列,稱爲內存溢出. 以發生的方式來分類,
內存泄漏
能夠分爲4類: 1.
常發
內存泄漏
。發生內存泄漏的代碼會被屢次執行到,每次被執行的時候都會致使一塊內存泄漏。 2. 偶發性內存泄漏。發生內存泄漏的代碼只有在某些特定環境或操做過程下才會發生。
常發
性和偶發性是相對的。對 於特定的環境,偶發性的也許就變成了
常發
性的。因此
測試環境
和測試方法對檢測內存泄漏相當重要。 3. 一次性內存泄漏。發生內存泄漏的代碼只會被執行一次,或者因爲算法上的缺陷,致使總會有一塊僅且一塊內存發 生泄漏。好比,在類的
構造函數
分配內存
,在
析構函數
中卻沒有釋放該內存,因此內存泄漏只會發生一次。 4. 隱式內存泄漏。程序在運行過程當中不停的
分配內存
,可是直到結束的時候才釋放內存。嚴格的說這裏並無發生內 存泄漏,由於最終程序釋放了全部申請的內存。可是對於一個服務器程序,須要運行幾天,幾周甚至幾個月,不及 時釋放內存也可能致使最終耗盡系統的全部內存。因此,咱們稱這類內存泄漏爲隱式內存泄漏。 從用戶使用程序的角度來看,內存泄漏自己不會產生什麼危害,做爲通常的用戶,根本感受不到內存泄漏的存在。 真正有危害的是內存泄漏的堆積,這會最終消耗盡系統全部的內存。從這個角度來講,一次性內存泄漏並無什麼危 害,由於它不會堆積,而隱式內存泄漏危害性則很是大,由於較之於常發性和偶發性內存泄漏它更難被檢測到 3、內存溢出 內存溢出的緣由以及解決方法 引發內存溢出的緣由有不少種,小編列舉一下常見的有如下幾種: 1.內存中加載的數據量過於龐大,如一次從數據庫取出過多數據; 2.集合類中有對對象的引用,使用完後未清空,使得JVM不能回收; 3.代碼中存在死循環或循環產生過多重複的對象實體; 4.使用的
第三方軟件
中的BUG; 5.啓動參數內存值設定的太小 內存溢出的解決方案: 第一步,修改JVM啓動參數,直接增長內存。(-Xms,-Xmx參數必定不要忘記加。) 第二步,檢查錯誤日誌,查看「OutOfMemory」錯誤前是否有其它異常或錯誤。 第三步,對代碼進行走查和分析,找出可能發生內存溢出的位置。 重點排查如下幾點: 1.檢查對數據庫查詢中,是否有一次得到所有數據的查詢。通常來講,若是一次取十萬條記錄到內存,就可能引發內 存溢出。這個問題比較隱蔽,在上線前,數據庫中數據較少,不容易出問題,上線後,數據庫中數據多了,一次查 詢就有可能引發內存溢出。所以對於數據庫查詢儘可能採用分頁的方式查詢。 2.檢查代碼中是否有死循環或遞歸調用。 3.檢查是否有大循環重複產生新對象實體。 4.檢查對數據庫查詢中,是否有一次得到所有數據的查詢。通常來講,若是一次取十萬條記錄到內存,就可能引發內 存溢出。這個問題比較隱蔽,在上線前,數據庫中數據較少,不容易出問題,上線後,數據庫中數據多了,一次查 詢就有可能引發內存溢出。所以對於數據庫查詢儘可能採用分頁的方式查詢。 5.檢查List、MAP等集合對象是否有使用完後,未清除的問題。List、MAP等集合對象會始終存有對對象的引用,使 得這些對象不能被GC回收。 第四步,使用內存查看工具動態查看內存使用狀況