JDK默认GC算法是个谜

JDK默认GC算法是个谜

背景

我们系统采用openjdk:8u212-b04-jdk-stretch作为基础镜像,java -version命令输出:

    openjdk version "1.8.0_212"
    OpenJDK Runtime Environment (build 1.8.0_212-b04)
    OpenJDK 64-Bit Server VM (build 25.212-b04, mixed mode)

从输出信息可以看出是1.8.0版本的OpenJDK。现在因为应用GC的一些问题,我们想知道它的默认GC算法。

下面是查找JDK默认GC算法是一些方法,其中方法一和方法二在我们这个OpenJDK没有用。

方法

方法一,PrintCommandLineFlags

命令行执行:java -XX:+PrintCommandLineFlags -version

理论上输出有开启GC的参数,如-XX:+UseParallelGC。我们这个没有。

方法二,PrintFlagsFinal

命令行执行:java -XX:+PrintFlagsFinal -version|grep Use|grep GC

理论上输出有GC算法开启状态为true。我们这个没有。

方法三,GarbageCollectorMXBean

	public static void main(String[] args) throws InstanceNotFoundException, MalformedObjectNameException, ReflectionException, MBeanException, NullPointerException{
		Object flags = ManagementFactory.getPlatformMBeanServer().invoke(
			    ObjectName.getInstance("com.sun.management:type=DiagnosticCommand"),
			    "vmFlags", new Object[] { null }, new String[] { "[Ljava.lang.String;" });
			for(String f: ((String)flags).split("\\s+"))
			    if(f.contains("GC")) System.out.println(f);
			for(GarbageCollectorMXBean gc: ManagementFactory.getGarbageCollectorMXBeans())
			    System.out.printf("%-20s%s%n", gc.getName(), Arrays.toString(gc.getMemoryPoolNames()));
	}

我们用上面java代码编写一个FindGC.java类,编译成FindGC.class,执行:java FindGC

我们的1.8.0版本OpenJDK的会输出:

    Copy                [Eden Space, Survivor Space]
    MarkSweepCompact    [Eden Space, Survivor Space, Tenured Gen]

我们加上-XX:+UseSerialGC参数,执行:java -XX:+UseSerialGC FindGC

会输出:

    -XX:+UseSerialGC
    Copy                [Eden Space, Survivor Space]
    MarkSweepCompact    [Eden Space, Survivor Space, Tenured Gen]

综上,我们基本可以确定1.8.0版本OpenJDK默认采用的GC算法是SerialGC。

方法四,jmap

jmap -heap PID(PID是某个java进程)会输出Java进程的堆信息,里面有些描述可以辅助推断GC算法。

-XX:+UseSerialGC,输出信息有“Mark Sweep Compact GC”,老年代标识是“tenured generation”。

-XX:+UseConcMarkSweepGC,输出信息有“Concurrent Mark-Sweep GC”,老年代标识是“concurrent mark-sweep generation”。

-XX:+UseParallelGC,输出信息有“Parallel GC with X thread(s)”(X是并发线程数),老年代标识是“PS Old Generation”。

-XX:+UseG1GC,输出信息有“Garbage-First (G1) GC with X thread(s)”(X是并发线程数),老年代标识是“G1 Old Generation”。

我们的1.8.0版本OpenJDK运行jmap -heap PID会输出“Mark Sweep Compact GC”且老年代标识是“tenured generation”,与SerialGC一样,

也基本可以确定默认GC算法是SerialGC。

总结

JDK开发者并没有提供直接的工具查看默认GC算法,我们只能通过一些辅助手段来确定。

参考

Is there a way to tell which GC algorithm the JVM is currently using

How to determine which GC I use?

Java 8最快的垃圾收集器是什么?

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值