JVM學習之 Java對象內存佈局

Java對象內存佈局

一個Java對象在內存中包括3個部分:對象頭、實例數據和對齊填充

在這裏插入圖片描述

一塊是非堆區,一塊是堆區。
堆區分爲兩大塊,一個是Old區,一個是Young區。
Young區分爲兩大塊,一個是Survivor區(S0+S1),一塊是Eden區。 Eden:S0:S1=8:1:1
S0和S1一樣大,也可以叫From和To。

在這裏插入圖片描述

根據之前對於Heap的介紹可以知道,一般對象和數組的創建會在堆中分配內存空間,關鍵是堆中有這麼多區
域,那一個對象的創建到底在哪個區域呢?

對象創建所在區域

一般情況下,新創建的對象都會被分配到Eden區,一些特殊的大的對象會直接分配到Old區。

對象分配 是年輕還是老
年輕;一次垃圾回收,歲數增加1,默認15
老年;當對象大小特別大的時候, 年齡特別大的時候

爲什麼young會出現 eden和s0,s1?

因爲分配對象,垃圾回收之後,對象需要連續的內存,但是不夠了,不連續,所以對象分配失敗,所以就出現了這三個區域。

爲什麼需要兩個Survivor區?

最大的好處就是解決了碎片化。也就是說爲什麼一個Survivor區不行?第一部分中,我們知道了必須設置Survivor區。假設
現在只有一個Survivor區,我們來模擬一下流程:
剛剛新建的對象在Eden中,一旦Eden滿了,觸發一次Minor GC,Eden中的存活對象就會被移動到Survivor區。這樣繼續循環下去,下一次Eden滿了的時候,問題來了,此時進行Minor GC,Eden和Survivor各有一些存活對象,如果此時把Eden區的
存活對象硬放到Survivor區,很明顯這兩部分對象所佔有的內存是不連續的,也就導致了內存碎片化。
永遠有一個Survivor space是空的,另一個非空的Survivor space無碎片

新生代中Eden:S1:S2爲什麼是8:1:1?

自己理解:是因爲s區必須要比例相等,爲了相互轉化,e區爲新生代,大多都是朝生夕死,產生快
新生代中的可用內存:複製算法用來擔保的內存爲9:1
可用內存中Eden:S1區爲8:1
即新生代中Eden:S1:S2 = 8:1:1

**擔保機制 **

當s0/s1不夠用 的時候,跟老年代借點空間 ,擔保
Minor GC、Major GC、Full GC
Minor GC:新生代 ,major gc通常會伴隨着minor gc,也就是會觸發full gc
Major GC:老年代
Full GC:新生代+老年代
比如有對象A,B,C等創建在Eden區,但是Eden區的內存空間肯定有限,比如有100M,假如已經使用了
100M或者達到一個設定的臨界值,這時候就需要對Eden內存空間進行清理,即垃圾收集(Garbage Collect),
這樣的GC我們稱之爲Minor GC,Minor GC指得是Young區的GC。
經過GC之後,有些對象就會被清理掉,有些對象可能還存活着,對於存活着的對象需要將其複製到Survivor區,然後再清空Eden區中的這些對象。

Survivor區詳解

由圖解可以看出,Survivor區分爲兩塊S0和S1,也可以叫做From和To。
在同一個時間點上,S0和S1只能有一個區有數據,另外一個是空的

Old區詳解

從上面的分析可以看出,一般Old區都是年齡比較大的對象,或者相對超過了某個閾值的對象。
在Old區也會有GC的操作,Old區的GC我們稱作爲Major GC,每次GC之後還能存活的對象年齡也會+1,如果年齡超過了某個閾值,就會被回收。

在這裏插入圖片描述

發佈了14 篇原創文章 · 獲贊 8 · 訪問量 835
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章