<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 前提環境 筆者JDK版本如下,如果不做指定的話,64為虛擬機1.8版本默認使用的`ParallelGC`垃圾收集器。 ``` $ java -XX:+PrintCommandLineFlags -version -XX:InitialHeapSize=134217728 -XX:MaxHeapSize=2147483648 -XX:+PrintCommandLineFlags -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseParallelGC java version "1.8.0_221" Java(TM) SE Runtime Environment (build 1.8.0_221-b11) Java HotSpot(TM) 64-Bit Server VM (build 25.221-b11, mixed mode) ``` 使用`-XX:+UseSerialGC`選擇Serial+ Serial Old的垃圾收集器組合來驗證如下內存分配和回收策略。 其中顯示默認使用的是。 ## 對象優先在Eden區分配 多數情況下,對象優先在Eden區分配。當Eden區沒有足夠的空間進行分配時,虛擬機將發起一次`Minor GC`。 可以添加`-XX:+PrintGCDetails`打印內存回收日志。 實例:(空的main方法在jdk1.8上運行得到如下日志) ``` # 堆大小為20M,新生代為10M,打印GC詳細信息 -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:+UseSerialGC ``` 日志如下: ``` Heap def new generation total 9216K, used 1996K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000) eden space 8192K, 24% used [0x00000007bec00000, 0x00000007bedf3198, 0x00000007bf400000) from space 1024K, 0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000) to space 1024K, 0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000) tenured generation total 10240K, used 0K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000) the space 10240K, 0% used [0x00000007bf600000, 0x00000007bf600000, 0x00000007bf600200, 0x00000007c0000000) Metaspace used 3012K, capacity 4496K, committed 4864K, reserved 1056768K class space used 330K, capacity 388K, committed 512K, reserved 1048576K ``` 通過日志可以知道: * 堆里年輕代共9216K(9M=Eden+S),其中Eden為8192K(8M),2個S區為1024K(1M)。其中已使用1996K,**說明虛擬機啟動后,其他線程已經占用了eden區1996K,也能說明對象是優先在Eden區分配的**。 * 堆里老年代共10240K(10M),已使用0K。 * 元數據區共4496K,已使用3208K,其中類空間容量388K,已使用353K。 ## 大對象直接進入老年代 虛擬機提供了一個`-XX:PretenureSizeThreshold`參數,**令大于這個設置值的對象直接在老年代分配**,避免大對象在Eden和2個Survivor區來回復制。 例子:(設置大對象閥值為3兆) ~~~ /** * 大對象直接進入老年代,對Serial和ParNew垃圾收集有效 * vm參數:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:+UseSerialGC -XX:PretenureSizeThreshold=3145728 */ public static void bigObj2old(){ byte[] a; a = new byte[4 * _1MB]; } ~~~ GC日志如下: ``` Heap def new generation total 9216K, used 1996K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000) eden space 8192K, 24% used [0x00000007bec00000, 0x00000007bedf3198, 0x00000007bf400000) from space 1024K, 0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000) to space 1024K, 0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000) tenured generation total 10240K, used 4096K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000) the space 10240K, 40% used [0x00000007bf600000, 0x00000007bfa00010, 0x00000007bfa00200, 0x00000007c0000000) Metaspace used 3199K, capacity 4496K, committed 4864K, reserved 1056768K class space used 352K, capacity 388K, committed 512K, reserved 1048576K ``` 通過日志可以知道,在設置了大對象閥值后,4M的對象確實被分配到了老年代。 **注意:參數XX:PretenureSizeThreshold只對Serial和ParNew收集器有效** ## 長期存活的對象將進入老年代 虛擬機給每個對象定義了對象年齡計數器(Age,在對象頭的`Mark Word`里),當對象到達15歲時(`-XX:MaxTenuringThreshold`默認值15),就會被晉升到老年代。 如果對象在Eden出生并且經過第一次Minor GC后存活且能被Survivor容納,就會被移動到Survivor空間,則對象年齡加1。 例子:(設置年齡閥值為1,且打印新生代各個對象年齡信息) ~~~ /** * 長期存活對象進入老年代 * vm參數:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:+UseSerialGC * -XX:MaxTenuringThreshold=1 -XX:+PrintTenuringDistribution */ public static void liveObj2old(){ byte[] a,b,c; a = new byte[_1MB / 4]; b = new byte[4 * _1MB]; c = new byte[4 * _1MB]; } ~~~ ``` [GC (Allocation Failure) [DefNew Desired survivor size 524288 bytes, new threshold 1 (max 1) - age 1: 685504 bytes, 685504 total : 6187K->669K(9216K), 0.0054269 secs] 6187K->4765K(19456K), 0.0054705 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] Heap def new generation total 9216K, used 4847K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000) eden space 8192K, 51% used [0x00000007bec00000, 0x00000007bf014930, 0x00000007bf400000) from space 1024K, 65% used [0x00000007bf500000, 0x00000007bf5a75c0, 0x00000007bf600000) to space 1024K, 0% used [0x00000007bf400000, 0x00000007bf400000, 0x00000007bf500000) tenured generation total 10240K, used 4096K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000) the space 10240K, 40% used [0x00000007bf600000, 0x00000007bfa00010, 0x00000007bfa00200, 0x00000007c0000000) Metaspace used 3209K, capacity 4496K, committed 4864K, reserved 1056768K class space used 354K, capacity 388K, committed 512K, reserved 1048576K ``` ## 動態對象年齡判斷 Survivor空間內相同年齡所有對象大小總和大于Survivor空間的一半,年齡大于等于的對象可以直接進入老年代,無須等到默認15歲。 例子: ~~~ /** * vm參數:-verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:+UseSerialGC * -XX:MaxTenuringThreshold=15 -XX:+PrintTenuringDistribution */ public static void dynamicAgeObj2old(){ byte[] a,b,c,d; a = new byte[_1MB / 4]; b = new byte[_1MB / 4]; // a + b 大于survivor空間一半 c = new byte[4 * _1MB]; d = new byte[4 * _1MB]; d = null; d = new byte[4 * _1MB]; } ~~~ GC日志如下: ``` [GC (Allocation Failure) [DefNew Desired survivor size 524288 bytes, new threshold 1 (max 15) - age 1: 921984 bytes, 921984 total : 6440K->900K(9216K), 0.0061563 secs] 6440K->4996K(19456K), 0.0061984 secs] [Times: user=0.00 sys=0.01, real=0.00 secs] [GC (Allocation Failure) [DefNew Desired survivor size 524288 bytes, new threshold 15 (max 15) - age 1: 1288 bytes, 1288 total : 5080K->1K(9216K), 0.0018378 secs] 9176K->4983K(19456K), 0.0018675 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] Heap def new generation total 9216K, used 4235K [0x00000007bec00000, 0x00000007bf600000, 0x00000007bf600000) eden space 8192K, 51% used [0x00000007bec00000, 0x00000007bf022a48, 0x00000007bf400000) from space 1024K, 0% used [0x00000007bf400000, 0x00000007bf400508, 0x00000007bf500000) to space 1024K, 0% used [0x00000007bf500000, 0x00000007bf500000, 0x00000007bf600000) tenured generation total 10240K, used 4982K [0x00000007bf600000, 0x00000007c0000000, 0x00000007c0000000) the space 10240K, 48% used [0x00000007bf600000, 0x00000007bfadda80, 0x00000007bfaddc00, 0x00000007c0000000) Metaspace used 3191K, capacity 4496K, committed 4864K, reserved 1056768K class space used 349K, capacity 388K, committed 512K, reserved 1048576K ``` 通過日志可以知道,survivor沒有被占用,說明a和b對象直接進入了老年代,并沒有等年齡到15。 ## 空間分配擔保 ![](https://img.kancloud.cn/78/de/78de365bd0599e6af2a1174d4a6f8f1a_1272x1482.png) 在GC開始前,會先判斷老年代最大可連續空間是否大于新生代所有對象總和,如果大于則說明無風險并執行Minor GC;如果不大于,再判斷是否開啟了空間分配擔保失敗,如果開啟了則再判斷老年代最大可以連續空間是否大于歷次晉升老年代對象的平均大小,若大于則冒著風險執行一次Minor GC;若不大于且不允許空間分配擔保失敗,則直接執行Full GC。 虛擬機使用`-XX:+HandlePromotionFailure`設置允許擔保失敗,該參數開啟后虛擬機在老年代最大可用連續空間大于歷次晉升老年代對象平均值情況下嘗試先執行Minor GC,其目的是為了盡可能避免Full GC。 `JDK 6 Update 24`之 后的規則變為只要老年代的連續空間大于新生代對象總大小或者歷次晉升的平均大小,就會進行Minor GC,否則將進行Full GC。 ## 參考資料 * 周志明 * 《深入理解Java虛擬機》
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看