Java架構師中的內存溢出和內存泄露是什麼?實際操做案例!

Java架構師中的內存溢出和內存泄露是什麼?實際操做案例!

JAVA中的內存溢出和內存泄露分別是什麼,有什麼聯繫和區別,讓咱們來看一看。緩存

01架構

內存泄漏 & 內存溢出ide

1.內存泄漏(memory leak )測試

申請了內存用完了不釋放,好比一共有 1024M 的內存,分配了 521M 的內存一直不回收,那麼能夠用的內存只有 521M 了,彷彿泄露掉了一部分;對象

通俗一點講的話,內存泄漏就是【佔着茅坑不拉shi】。blog

2.內存溢出(out of memory)生命週期

申請內存時,沒有足夠的內存可使用;內存

通俗一點兒講,一個廁所就三個坑,有兩個站着茅坑不走的(內存泄漏),剩下最後一個坑,廁所表示接待壓力很大,這時候一會兒來了兩我的,坑位(內存)就不夠了,內存泄漏變成內存溢出了。資源

可見,內存泄漏和內存溢出的關係:內存泄露的增多,最終會致使內存溢出。hash

這是一個頗有味道的例子。
Java架構師中的內存溢出和內存泄露是什麼?實際操做案例!

如上圖:

對象 X 引用對象 Y,X 的生命週期比 Y 的生命週期長;

那麼當Y生命週期結束的時候,X依然引用着Y,這時候,垃圾回收期是不會回收對象Y的;

若是對象X還引用着生命週期比較短的A、B、C,對象A又引用着對象 a、b、c,這樣就可能形成大量無用的對象不能被回收,進而佔據了內存資源,形成內存泄漏,直到內存溢出。

02

泄漏的分類

·

常常發生:發生內存泄露的代碼會被屢次執行,每次執行,泄露一塊內存;

·

·

偶然發生:在某些特定狀況下才會發生;

·

·

一次性:發生內存泄露的方法只會執行一次;

·

·

隱式泄露:一直佔着內存不釋放,直到執行結束;嚴格的說這個不算內存泄露,由於最終釋放掉了,可是若是執行時間特別長,也可能會致使內存耗盡。

03

致使內存泄漏的常見緣由

  1. 循環過多或死循環,產生大量對象;

  2. 靜態集合類引發內存泄漏,由於靜態集合的生命週期和 JVM 一致,因此靜態集合引用的對象不能被釋放;下面這個例子中,list 是靜態的,只要 JVM 不停,那麼 obj 也一直不會釋放。

Java架構師中的內存溢出和內存泄露是什麼?實際操做案例!

  1. 單例模式,和靜態集合致使內存泄露的緣由相似,由於單例的靜態特性,它的生命週期和 JVM 的生命週期同樣長,因此若是單例對象若是持有外部對象的引用,那麼這個外部對象也不會被回收,那麼就會形成內存泄漏。

  2. 數據鏈接、IO、Socket鏈接等等,它們必須顯示釋放(用代碼 close 掉),不然不會被 GC 回收。
    Java架構師中的內存溢出和內存泄露是什麼?實際操做案例!

  3. 內部類的對象被長期持有,那麼內部類對象所屬的外部類對象也不會被回收。

  4. Hash 值發生改變,好比下面中的這個類,它的 hashCode 會隨着變量 x 的變化而變化:

Java架構師中的內存溢出和內存泄露是什麼?實際操做案例!
Java架構師中的內存溢出和內存泄露是什麼?實際操做案例!

能夠看到,在測試方法中,當元素的 hashCode 發生改變以後,就再也找不到改變以前的那個元素了;

這也是 String 爲何被設置成了不可變類型,咱們能夠放心地把 String 存入 HashSet,或者把 String 當作 HashMap 的 key 值;

當咱們想把本身定義的類保存到散列表的時候,須要保證對象的 hashCode 不可變。

  1. 內存中加載數據量過大;以前項目在一次上線的時候,應用啓動奇慢直到夯死,就是由於代碼中會加載一個表中的數據到緩存(內存)中,測試環境只有幾百條數據,可是生產環境有幾百萬的數據。

專一於Java架構師技術分享,撩我免費送Java全套架構師晉級資料

(Java架構師交流企Q鵝裙/:445-820-908 )

相關文章
相關標籤/搜索