写点什么

原来书中说的 JVM 默认垃圾回收器是错的!

  • 2021 年 11 月 11 日
  • 本文字数:1646 字

    阅读完需:约 5 分钟

-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?这时候我有两个猜想


  1. PS MarkSweep 只是回收器的别名,他可以指代 Serial Old 和 Parallel Old,毕竟他们的实现基本一样。

  2. -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


【一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


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)

评论

发布
暂无评论
原来书中说的JVM默认垃圾回收器是错的!