<form id="dlljd"></form>
        <address id="dlljd"><address id="dlljd"><listing id="dlljd"></listing></address></address>

        <em id="dlljd"><form id="dlljd"></form></em>

          <address id="dlljd"></address>
            <noframes id="dlljd">

              聯系我們 - 廣告服務 - 聯系電話:
              您的當前位置: > 關注 > > 正文

              世界今熱點:躲過15次GC之后 進入老年代系統有哪些規則?

              來源:CSDN 時間:2023-03-30 16:07:54

              1.躲過15次GC之后進入老年代

              系統剛啟動時,創建的各種各樣的對象,都是分配在年輕代里。隨著慢慢系統跑著跑著,年輕代滿了,就會出發Minor GC ,可能1%的少量存活對像轉移到空著的Survivor區中,然后系統繼續運行,繼續在Eden區里分配對象........,類似靜態變量等引用的對象,可能存活時間會久一些,無論年輕代中怎么垃圾回收,類似這種對象都不會被回收掉。而此對象每次在年輕代里躲過一次Minor GC被轉移到一塊Survivor區域中,他的年齡就會增加一歲,默認的設置下,當對象的年齡達到15歲時,也就是躲過15次GC的時候,他就會轉移到老年代里去,具體是多少歲進入老年代,可以通過JVM參數“-XX:MaxTenuringThreshold”來設置,默認是15歲


              【資料圖】

              2.動態對象年齡判斷

              這里跟這個對象年齡有另外一個規則可以讓對象進入老年代,不用等到15次GC過后才可以。

              假設這個圖中的Survivor2區有兩個對象,這倆對象的年齡一樣,都是2歲,然后倆對象加起來內存超過了50MB,這個時候,Survivor2區里大于等于2歲的對象,都要進入老年代里去。這就是動態年齡判斷的規則,這條規則也會讓一些年輕代的對象進入老年代,另外實際這個規則運行的時候是如下的邏輯:年齡1+年齡2+年齡n的多個年齡對象總和超過了Survivor區的50%,此時就會把年齡n以上的對象都放入老年代。

              3.大對象直接進入老年代

              有一個JVM參數,就是“-XX:PretenureSizeThreshold”,可以把它的值設置為字節數,比如“1048576”字節,就是1MB,意思就是如果你要創建一個大于這個大小的對象,比如一個超大的數組,或者是別的啥東西,此時就直接把這個大對象放到老年代里去,壓根不會經過年輕代。之所以這么做,是因為要避免年輕代里出現那種大對象,然后屢次躲過GC,還得把他在兩個Survivor區域里來回復制多次之后才能進入老年代。所以說這也是一個對象進入老年代的規則

              4.Minor GC后的對象太多,無法放入Survivor區

              如圖所示:

              這個時候就必須得把這些對象直接轉移到老年代去!

              5.老年代空間分配擔保規則

              如果年輕代里大量對象存活,確實自己的Survivor區放不下了,必須轉移到老年代去

              但是如果老年代里空間也不夠放這些對象,改怎么辦呢?

              首先,在執行任何一次Minor GC之前,JVM都會先檢查一些老年代可用的內存空間,是否大于年輕代所有對象的總大小,為什么呢?因為最極端的情況下,可能年輕代Minor GC之后,所有對象都存活下來了,那豈不是年輕代所有對象全部進入老年代

              如果說發現老年代內存大小是大于年輕代所有對象的,此時就可以放心大膽地對年輕代發起一次Minor GC了。

              但是假如執行Minor GC之前,發現老年代的可用內存已經小于了年輕代的全部對象大小了

              恰好這個時候Minor GC之后年輕代的對象全部存活下來,全部需要轉移到老年代中去,但是老年代內存空間又不夠?

              所以假如Minor GC之前,發現老年代的可用內存已經小于了年輕代的全部對象大小,就會看一個“-XX:-HandlePromotionFailure”的參數是否設置了

              如果有這個參數,那么就會看看老年代的內存大小,是否大于之前每一次Minor GC后進去老年代對象的平均大小

              但是如果上面步驟判斷失敗了,或者是“-XX:-HandlePromotionFailure”參數沒設置,此時就會直接觸發一次“Full GC”,

              就是對老年代進行垃圾回收,盡量騰出來一些內存空間,然后再執行Minor GC。

              如果上面兩個步驟判斷成功,那么就可以嘗試Minor GC,此時進行Minor GC有幾種可能:

              ①Minor GC過后,剩余的存活對象的大小,小于Survivor區的大小,那么此時存活對象進入Survivor區即可

              ②Minor GC過后,剩余的存活對象的大小,大于Survivor區的大小,但是小于老年代可用內存大小,就直接進入老年代即可

              ③Minor GC過后,剩余的存活對象的大小,大于Survivor區的大小,同時大于老年代可用內存大小,此時就會發生“Handle Promotion Failure”的情況,這個時候就會出發一次“Full GC”。

              Full GC就是對老年代進行垃圾回收,同時也一般會對年輕代進行垃圾回收。

              如果Full GC之后,老年代還是沒有足夠空間存放Minor GC過后的剩余存活對蝦,此時就會導致所謂的“OOM”內存溢出了

              所以,所謂的JVM優化,就是盡可能的讓對象都在年輕代里分配和回收,盡量別讓太多對象頻繁進入老年代,避免頻繁對老年代進行垃圾回收,同時給系統充足的內存大小,避免年輕代頻繁的進行垃圾回收。

              責任編輯:

              標簽:

              相關推薦:

              精彩放送:

              新聞聚焦
              Top 中文字幕在线观看亚洲日韩