天天看點

深入了解JVM(四)JVM記憶體模型細講之堆前言堆細講堆大小參數:堆空間分代劃分

深入了解JVM(四)JVM記憶體模型細講之堆

  • 前言
  • 堆細講
  • 堆大小參數:
    • 記憶體溢出
  • 堆空間分代劃分

前言

上文就講了JVM記憶體的五部分,Java方法區、Java棧、Native方法區、Java堆和程式計數器本文就詳細詳解下

堆細講

堆是 JVM 上最大的記憶體區域,我們申請的幾乎所有的對象,都是在這裡存儲的。我們常說的垃圾回收,操作的對象就是堆。

堆空間一般是程式啟動時,就申請了,但是并不一定會全部使用。堆一般設定成可伸縮的。 随着對象的頻繁建立,堆空間占用的越來越多,就需要不定期的對不再使用的對象進行回收。這個在 Java 中,就叫作 GC(Garbage Collection)。

那一個對象建立的時候,到底是在堆上配置設定,還是在棧上配置設定呢?這和兩個方面有關:對象的類型和在 Java 類中存在的位置。 Java 的對象可以分為基本資料類型和普通對象。 對于普通對象來說,JVM 會首先在堆上建立對象,然後在其他地方使用的其實是它的引用。比如,把這個引用儲存在虛拟機棧的局部變量表中。 對于基本資料類型來說(byte、short、int、long、float、double、char),有兩種情況。 當你在方法體内聲明了基本資料類型的對象,它就會在棧上直接配置設定。其他情況,都是在堆上配置設定。

堆大小參數:

-Xms:堆的最小值;

-Xmx:堆的最大值;

-Xmn:新生代的大小;

-XX:NewSize;新生代最小值;

記憶體溢出

堆溢出 記憶體溢出:申請記憶體空間,超出最大堆記憶體空間。

如果是記憶體溢出,則通過 調大 -Xms,-Xmx 參數。 如果不是記憶體洩漏,就是說記憶體中的對象卻是都是必須存活的,那麼久應該檢查 JVM 的堆參數設定,與機器的記憶體對比,看是否還有可以調整的空間, 再從代碼上檢查是否存在某些對象生命周期過長、持有狀态時間過長、存儲結構設計不合理等情況,盡量減少程式運作時的記憶體消耗。

堆空間分代劃分

堆被劃分為新生代和老年代(Tenured),新生代又被進一步劃分為 Eden 和 Survivor 區,最後 Survivor 由 From Survivor 和 To Survivor 組成。

深入了解JVM(四)JVM記憶體模型細講之堆前言堆細講堆大小參數:堆空間分代劃分

具體的垃圾回收之後的文章中講解