日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

研究了 2 天,终于知道 JDK 8 默认 GC 收集器了!

發布時間:2025/3/21 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 研究了 2 天,终于知道 JDK 8 默认 GC 收集器了! 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

JDK 8 到底默認用的是哪款 GC 收集器?

為啥是 JDK8?不是 9 也不是 10?因為 JDK8 還是市場占有率最高的,所以針對這個版本我做了深入的探索。

《深入理解 Java 虛擬機》第三版第 128 頁中提到 JDK 9 之前,Server 默認使用 Parallel Scavenge + Serial Old(PS MarkSweep),那么真的是這樣的嗎??我帶著這個疑問做了如下驗證

  • 直接使用命令查看一下當前 JVM 默認參數

  • java?-XX:+PrintCommandLineFlags?-version

    輸入內容如下

    -XX:InitialHeapSize=268435456? -XX:MaxHeapSize=4294967296? -XX:+PrintCommandLineFlags? -XX:+UseCompressedClassPointers? -XX:+UseCompressedOops? -XX:+UseParallelGC java?version?"1.8.0_162" Java(TM)?SE?Runtime?Environment?(build?1.8.0_162-b12) Java?HotSpot(TM)?64-Bit?Server?VM?(build?25.162-b12,?mixed?mode)

    第 6 行我們可以看到使用的是-XX:+UseParallelGC按照書中或者是網上的文章發現,設置這個參數以后默認就是如下兩個組合,新生代用Parallel Scavenge老年代用Serial Old

    Parallel Scavenge + Serial Old

    那么這里再詳細科普一下,下面是每個參數對應的回收器的類型

    將信將疑的我再次開啟探索之旅,這時候我使用ManagementFactory.getGarbageCollectorMXBeans()把具體的回收器打印出來看下不就可以了嗎?詳細代碼如下

    import?java.lang.management.GarbageCollectorMXBean; import?java.lang.management.ManagementFactory; import?java.util.List; public?class?GcCollectorPrinter?{public?static?void?main(String[]?args)?{List<GarbageCollectorMXBean>?beans?=?ManagementFactory.getGarbageCollectorMXBeans();for?(GarbageCollectorMXBean?bean?:?beans)?{System.out.println(bean.getName());}} }

    直接運行輸出內容如下

    PS Scavenge PS MarkSweep

    這意思是PS MarkSweep是Serial Old的意思對嗎?那么-XX:+UseParallelOldGC打印出來的結果又是什么呢?我配置好參數再次運行如下兩個命令

    javac?GcCollectorPrinter.java? java?-XX:+UseParallelOldGC?GcCollectorPrinter

    如下是打印結果

    PS?Scavenge
    PS?MarkSweep

    等等,我更加疑惑了?-XX:+UseParallelOldGC和 ?-XX:+UseParallelGC的輸出結果都是PS MarkSweep,那么他究竟是Serial Old還是Parallel Old?
    這時候我有兩個猜想

  • PS MarkSweep只是回收器的別名,他可以指代Serial Old和Parallel Old,畢竟他們的實現基本一樣。

  • -XX:+UseParallelGC和-XX:+UseParallelOldGC結果一樣,都是用的Parallel Old

  • 好的那么接下來開啟 GC 之旅,這個"別名"一樣沒辦法了,我直接打印一下 GC 的日志,看下日志里面顯示什么,-XX:+PrintGCDetails這個參數就上場了,他可以輸出 GC 詳細的分區分析,我們再次運行剛才的兩個例子如下

    java?-XX:+UseParallelOldGC?-XX:+PrintGCDetails?GcCollectorPrinter
    java?-XX:+PrintGCDetails?GcCollectorPrinter

    結果驚人的一致

    PS Scavenge PS MarkSweep Heap PSYoungGen total 76288K, used 3932K [0x000000076ab00000, 0x0000000770000000, 0x00000007c0000000) eden space 65536K, 6% used [0x000000076ab00000,0x000000076aed7240,0x000000076eb00000) from space 10752K, 0% used [0x000000076f580000,0x000000076f580000,0x0000000770000000) to space 10752K, 0% used [0x000000076eb00000,0x000000076eb00000,0x000000076f580000) ParOldGen total 175104K, used 0K [0x00000006c0000000, 0x00000006cab00000, 0x000000076ab00000) object space 175104K, 0% used [0x00000006c0000000,0x00000006c0000000,0x00000006cab00000) Metaspace used 2729K, capacity 4486K, committed 4864K, reserved 1056768K class space used 297K, capacity 386K, committed 512K, reserved 1048576K

    可以看到 老年代都是用的ParOldGen那么一點可以斷定了,-XX:+UseParallelGC和-XX:+UseParallelOldGC結果一樣,都是用的Parallel Old。

    那么我們繼續驗證第二個疑問,PS MarkSweep只是回收器的別名,他可以指代Serial Old和Parallel Old,可以直接使用如下命令驗證,我用的不是+而是-,這樣就一定強制去掉了Parallel Old收集器,我們看下效果

    java?-XX:-UseParallelOldGC?-XX:+PrintGCDetails?GcCollectorPrinter

    PS Scavenge PS MarkSweep Heap PSYoungGen total 76288K, used 3932K [0x000000076ab00000, 0x0000000770000000, 0x00000007c0000000) eden space 65536K, 6% used [0x000000076ab00000,0x000000076aed7240,0x000000076eb00000) from space 10752K, 0% used [0x000000076f580000,0x000000076f580000,0x0000000770000000) to space 10752K, 0% used [0x000000076eb00000,0x000000076eb00000,0x000000076f580000) PSOldGen total 175104K, used 0K [0x00000006c0000000, 0x00000006cab00000, 0x000000076ab00000) object space 175104K, 0% used [0x00000006c0000000,0x00000006c0000000,0x00000006cab00000) Metaspace used 2728K, capacity 4486K, committed 4864K, reserved 1056768K class space used 297K, capacity 386K, committed 512K, reserved 1048576K

    唯一的變化就是ParOldGen換成了PSOldGen,經過查詢我們可以確定PSOldGen就是 ?Serial Old所以終于有了答案。

  • PS MarkSweep只是回收器的別名,他可以指代Serial Old和Parallel Old。

  • -XX:+UseParallelGC和-XX:+UseParallelOldGC結果一樣,都是用的Parallel Old

  • 那書上說的還能有假?保險起見還是去找一些資料吧

    在 JDK 8 的官網找到了一些蛛絲馬跡
    鏈接:https://urlify.cn/67NnEz

    Parallel compaction is enabled by default if the option -XX:+UseParallelGC has been specified. The option to turn it off is -XX:-UseParallelOldGC.

    大致意思就是說-XX:+UseParallelGC就會開始Parallel收集器除非手動關閉,那么可是書上為什么說是Serial呢?

    終于我在 JDK 源碼 commit 記錄里面找到了答案,在 JDK 7U4 之前確實?UserParallelGC?用的就是?Serial,在這個版本之后?Parallel?已經很成熟了,所以直接替換了舊的收集器,所以 JDK 7u4 以后的 7 和 JDK 8 老年代默認使用的都是?Parallel?收集器,只是書中沒有更新這個細節。
    網址:
    https://bugs.openjdk.java.net/browse/JDK-6679764
    http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/rev/24cae3e4cbaa
    原文:

    Server-class machine ergonomics was introduced in jdk5. If the machine upon which
    the jvm is running is powerful enough (currently, at least 2 physical cores plus
    at least 2gb of memory), the server jvm is invoked using the parallel scavenger
    rather than the serial scavenger. Currently the old gen collector used is
    serial mark-sweep-compact. Now that the parallel old gen collector is mature,
    we should change to using it instead.
    Issue Links

    總結

    以上是生活随笔為你收集整理的研究了 2 天,终于知道 JDK 8 默认 GC 收集器了!的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。