堆內存分配策略傻傻不清楚

程序員小迷 2024-05-04 12:00:56

一、概述

1.JVM堆內存分爲年輕代、老年代和持久代(JDK7及之前版本)或元空間(JDK8及之後版本)。

年輕代用于存放新創建的對象,老年代用于存放存活時間較長的對象。

持久代或元空間主要用于存放類信息、方法信息、常量池等。持久代在JDK7及之前的版本中容易出現內存溢出,因此在JDK8之後被元空間所替代。

2.年輕代包括一個Eden區和2個Survior區。對象優先在Eden分配,若Eden內存空間不足,就會發生Minor GC,存活的對象會移到另一個Survior區。多次Minor GC後仍然存活的對象會晉升到老年代。

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

大對象:需要大量連續內存空間的Java對象,比如很長的字符串和大型數組:

1)需要內存有空間,還是需要提前進行垃圾回收以獲取連續空間來存放大對象。

2)會進行大量的內存複制。

-XX:PretenureSizeThreshold 參數 ,大于這個數量直接在老年代分配,缺省爲0 ,表示絕不會直接分配在老年代。

4.長期存活的對象將進入老年代。默認15歲,可由JVM參數-XX:MaxTenuringThreshold調整。

5.動態對象年齡判定。爲了能更好地適應不同程序的內存狀況,虛擬機並不是永遠地要求對象的年齡必須達到了MaxTenuringThreshold才能晉升老年代。如果在Survivor空間中相同年齡所有對象大小的總和大于Survivor空間的一半,年齡大于或等于該年齡的對象就可以直接進入老年代,無須等到MaxTenuringThreshold中要求的年齡。

6.空間分配擔保:新生代中有大量的對象存活,Survivor空間不夠,當出現大量對象在Minor GC後仍然存活的情況(最極端的情況就是內存回收後新生代中所有對象都存活),就需要老年代進行分配擔保,把Survivor無法容納的對象直接進入老年代。只要老年代的連續空間大于新生代對象的總大小或者曆次晉升的平均大小,就進行Minor GC,否則進行Full GC。

二、總結

1.JVM在創建對象時,會根據對象的類型和大小來決定在堆內存中的哪個區域進行分配。

2.對象優先分配在Eden區。

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

4.長期存活的對象將進入老年代。

5.動態對象年齡判定。

6.空間分配擔保。

微風不燥,陽光正好,你就像風一樣經過這裏,願你停留的片刻溫暖舒心。

我是程序員小迷(致力于C、C++、Java、Kotlin、Android、Shell、JavaScript、TypeScript、Python等編程技術的技巧經驗分享),若作品對您有幫助,請關注、分享、點贊、收藏、在看、喜歡,您的支持是我們爲您提供幫助的最大動力。

歡迎關注。助您在編程路上越走越好!

0 阅读:15

程序員小迷

簡介:致力于Android、C等編程技術的技巧經驗分享