JVM 物件怎麼到的老年代

2021-10-20 10:01:18 字數 1839 閱讀 1088

jvm堆記憶體主要分為新生代和老年代,minor gc就是**新年帶的gc,也稱為young gc,老年代的gc 就是 full gc。

新生代又分為eden區和兩個servivor區,這個在下面的時候可能會用到。(兩個servivor區就簡稱為s1區和s2區)

每次物件新生成的時候,會在eden區生成,如果eden區滿了,就會發生一次minor gc,這個時候會把eden區還存活的物件複製到s1區,這個時候從eden區到s1去的物件,他們的年齡就開始計數了,等下次發生minor gc的時候s1存活的物件會複製到s2區,這個時候存活的物件的年齡就會加1,這樣躲過15次之後的物件會把這樣的物件放到老年代。

那麼這個15次是不是可以修改的?這個肯定是可以修改的,我們可以使用-xx:maxtenuringthreshold來設定多少次之後會進入老年代,預設是15次。

那麼我們可以把這個物件設定成很大很大麼?這肯定是不行的,這個值最大就是15。

為什麼最大是15呢?這個就需要去看看物件頭的資訊了,在物件頭裡面有個儲存gc次數的位置,jvm預留了4個位元組來儲存,所以4個位元組做大的15了,當然了,我前幾年也看到過說可以設定更大的,但是我現在覺得這個值要是改的話,並沒有想象中的那麼好改。

如果咱們s1區的大小就100m,這樣的話如果每次minor gc都會產生30m的存活會比較久的物件,這個時候,可能進行了4次minor gc之後s區就滿了,所以這裡jvm做了一些優化。

當minor gc之後,s區存活的物件大小,大於50%的時候會把部分物件直接複製到老年代。

那怎麼判斷哪些物件需要到老年代的呢?年齡1+年齡2+年齡n的對個年齡的總和超過了s1區的50%,這個時候就會把大於等於年齡n的物件都放入老年代。

在jvm引數裡面,-xx:pretenuresizethreshold就是,當乙個物件的大小超過多少的時候,就可以直接把該物件直接放入老年代,不用經過s區。

這個就非常好理解了,如果大物件頻繁的出現在s區,會把一些應該**的一些小物件直接進入到老年代。

這個也是我們在做jvm優化的時候需要考慮的乙個點,希望在以後的工作中,如果遇到這樣的問題,不會不知道。

在什麼情況下eden區的存活物件會直接到老年代呢?

當minor gc之後發現剩餘的存活物件太多了,沒有辦法放入帶另外一塊s區的時候,jvm會把這些物件直接放入到老年代中。

這個說起來可能就有點早了,在jdk 6 update 24之前,在發生minor gc之前,虛擬機器必須先檢查老年代最大可用的連續空間是否大於新生代所有物件總空間,如果這個條件成立,那這一次minor gc可以確保是安全的。如果不成立,則虛擬機會先檢視-xx:handlepromotionfailure引數的設定值是否允許擔保失敗(handlepromotion failure);如果允許,那會繼續檢查老年代最大可用的連續空間是否大於歷次晉公升到老年代物件的平均大小,如果大於,將嘗試進行一次minor gc,儘管這次minor gc是有風險的;如果小於,或者-xx:handlepromotionfailure設定不允許冒險,那這時就要改為進行一次fullgc。

在jdk 6 update 24之後不再使用-xx:handlepromotionfailure引數了,jdk 6 update 24之後的規則變為只要老年代的連續空間大於新生代物件總大小或者歷次晉公升的平均大小,就會進行minor gc,否則將進行full gc。

這個大家記下來就好了,可能在未來的面試的時候可能會問到。

其實沒什麼可以總結的地方,明白了這些物件是怎麼進入到的老年代,我們在以後優化的時候,就可以判斷是不是有我們設定不太對的地方,然後去調整。

可以根據gc的日誌看到在什麼時候什麼發生的gc,根據對應區域的變化來對線上的系統進行一些優化。

JVM 調整進入老年代的年齡

長期存活物件進入老年代 虛擬機器採用分代收集的思想來管理記憶體,記憶體 時必須識別哪些物件放入新生代,哪些物件放入老年代。為了做到這點,虛擬機器為每個物件定義了乙個物件年齡計數器。如果物件在eden出生並經過一次minor gc仍然存活,並且能被survivor容納,將被移動到survivor區,並...

聊聊JVM分代模型 年輕代 老年代 永久代

jvm記憶體的乙個分代模型 年輕代 老年代 永久代。注 在1.8以後,永久代被移除,轉而用元空間代替。這裡主要是介紹一下概念。1.背景引入 1 package com.test.day11 23 public class testjvm 9 10private static void getstri...

優化老年代引數的分析思路

老年代優化的基調 避免物件過快進入老年代 進而思考 什麼情況物件會進入老年代?什麼情況物件會提前進入老年代?參考 什麼時候會觸發老年代gc 和 minor gc前後的幾種特殊情況 每次minor gc後,根據執行耗時 qps 每次執行產生物件大小 來計算出 存活物件的總大小,注意 suvivor 區...