jvm動態年齡計算規則以及為什麼要這樣做

2021-10-17 08:58:55 字數 1335 閱讀 6790

有乙個關鍵引數targetsurvivorratio。這個引數是年輕代物件動態晉公升老年代的關鍵引數。下面是虛擬機器中晉公升老年代計算的**。

uint agetable::compute_tenuring_threshold(size_t survivor_capacity) 

uint result = age < maxtenuringthreshold ? age : maxtenuringthreshold;

...}

翻譯上面的**就是:

1、通過survivor區記憶體值的大小和這個關鍵比率來計算乙個期望值,desired_survivor_size 。

2、定義乙個total計數器,累加每個年齡段物件大小的總和。

3、當total大於期望值desired_survivor_size 時停止累加。

4、比較當前age和maxtenuringthreshold 哪個更小,將其作為下一次晉公升老年代的基準值

我們可以通過-xx:targetsurvivorratio這個引數來制定這個比率,但是議案不會調整他。

大致邏輯就是,遍歷物件的時候,從年齡由小到大進行累加,當加到某個年齡之後,發現記憶體總和大於了那個上面計算的那個期望值,就從這個年齡段開始把以上的物件都放在老年代中

但是我們應該能想到,不是有個-xx:maxtenuringthreshold這個引數來指定最大物件嗎,這裡為什麼還要做乙個動態的判斷呢?

jvm引入動態年齡計算,主要基於如下兩點考慮:

1、如果沒有動態計算,固定按照maxtenuringthreshold設定的閾值作為晉公升條件:

a)maxtenuringthreshold設定的過大,原本應該晉公升的物件一直停留在survivor區,直到survivor區大小不足以滿足完成一次minorgc時,jvm會將eden+svuvivor中存活的一股腦全部移動到老年代,不管物件的年齡是多少。這樣物件老化的機制就失效了。

b)maxtenuringthreshold設定的過小,那麼物件就會更早的被移動到老年代,物件不能在新生代充分被**,大量短期物件被晉公升到老年代,老年代空間迅速增長,引起頻繁的major gc。分代**失去了意義,嚴重影響gc效能。

2、應用程式在不同時間節點上的請求量與併發量都不同:特殊任務的執行或者流量成分的變化,都會導致物件的生命週期分布發生波動,那麼固定的閾值設定,因為無法動態適應變化,會造成和上面相同的問題。

總結來說,為了更好的適應不同程式的記憶體情況,虛擬機器並不總是要求物件年齡必須達到maxtenuringthreshhold再晉級老年代。而是通過這種方式來實現老年代的晉公升。

記憶體對齊規則以及作用

首先由乙個程式引入話題 1 環境 vc6 windows sp22 程式13 include 45 using namespace std 6 7struct st1 8 13 14struct st2 15 20 21int main 22 27 程式的輸出結果為 sizeof st1 is 12...

記憶體對齊的規則以及作用

首先由乙個程式引入話題 include using namespace std struct st1 struct st2 int main cout 程式的輸出結果為 sizeof st1 is 12 sizeof st2 is 8 問題出來了,這兩個一樣的結構體,為什麼sizeof的時候大小不一...

記憶體對齊的規則以及作用

首先由乙個程式引入話題 1 環境 vc6 windows sp22 程式13 include iostream 45 using namespace std 67 struct st1 8 1314 struct st215 20 21int main 2227 程式的輸出結果為 sizeof st...