查找正在运行的垃圾收集器类型

后 JSE5人机工程学旨在为您自动选择适当类型的垃圾收集器(以及其他事情)。

我想知道是否有任何方法可以确认/知道垃圾收集器的类型和 JVM 人机工程学所选择/当前设置的性能目标。

65835 次浏览

您可以使用 JRE 的 -XX标志来选择所选择的垃圾收集器。

使用5.0 Java TM 虚拟机优化垃圾收集

此外,还可以使用 JConsole监视垃圾收集。

不能直接回答你的问题但我相信这就是你要找的。

根据 爪哇6文档 12(不仅仅是 Java5) :

参考 1表示:

对象的服务器类计算机上 服务器 VM,垃圾收集器(GC) 与上一个系列相比有所改变 并行收集器[ ... ]

参考 2表示:

从 J2SE 5.0开始,当 应用程序启动,启动程序 可以尝试检测 应用程序运行在 “ server-class”机器,如果是,则使用 虚拟服务器 机器(服务器 VM) ,而不是 客户端虚拟机 (客户端 VM)。

此外,参考 2表示:

注意: 对于 JavaSE6, 服务器类机器是一个具有 至少2个 CPU 和至少2GB 的 物理记忆。

根据这些信息,您可以知道如果盒子是一个服务器(根据 2) ,那么它将使用并行 GC。您还可以推断它不会在运行时更改 GC。

如果进一步深入研究文档,您可能会发现非服务器机器的正确答案。

这里有一些关于如何 以编程方式获取 GC 信息的信息,但是看起来它可能需要事先知道 GC 的名称。真麻烦。

编辑: 尝试 ManagementFactory.getGarbageCollectorMXBeans()并迭代返回的列表。其中一个将是活动的。

java -XX:+PrintCommandLineFlags -version

将显示您的默认垃圾收集器。我还发现下面的页面有用的 详细说明各种操作系统的默认垃圾收集器

import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.util.List;


public class GCInformation {


public static void main(String[] args) {
try {
List<GarbageCollectorMXBean> gcMxBeans = ManagementFactory.getGarbageCollectorMXBeans();


for (GarbageCollectorMXBean gcMxBean : gcMxBeans) {
System.out.println(gcMxBean.getName());
System.out.println(gcMxBean.getObjectName());
}


} catch (RuntimeException re) {
throw re;
} catch (Exception exp) {
throw new RuntimeException(exp);
}
}
}

例如,尝试下面的命令来了解不同的 GC 类型

java -XX:+PrintCommandLineFlags  GCInformation
java -XX:+PrintCommandLineFlags -XX:+UseParallelGC GCInformation
java -XX:+PrintCommandLineFlags -XX:+UseConcMarkSweepGC -XX:+UseParNewGC GCInformation
java -XX:+PrintCommandLineFlags -XX:+UseConcMarkSweepGC -XX:-UseParNewGC GCInformation
-XX:+PrintGC
-XX:+PrintGCDetails

这将打印使用的 GC。在我的例子中,它打印:

[GC (Allocation Failure) [PSYoungGen: 348192K->32K(348672K)] 356792K->8632K(1048064K), 0.0111518 secs] [Times: user=0.00 sys=0.00, real=0.01 secs]

这意味着 并行垃圾收集器正在被年轻一代使用。“分配失败”是指由于年轻代堆部分中没有足够的空间而启动垃圾收集。

(适用于 Java < = 8)

这个命令打印正在运行的 JVM 的 GC 类型:

jmap -heap <pid> | grep GC

对于现代计算机(多 CPU、大内存) ,JVM 将作为服务器机器检测它,并默认使用 Parallel GC,除非通过 JVM 标志明确指定使用哪个 gc。

例如:

jmap -heap 26806 | grep GC

产出:

具有8个线程的并行 GC


@ Update-for Java9 +

(感谢 @ JakeRobb的评论。)

从 Java9开始,有两个变化与这个问题相关:

  • 需要使用 jhsdb附加到 Java 进程或启动调试器。
    请参阅: < a href = “ https://docs.oracle.com/javase/9/tools/jhsdb.htm”rel = “ norefrer”> jhsdb
  • 默认的 gc 更改为 G1

命令格式:

jhsdb jmap --heap --pid <pid> | grep GC

例如:

jhsdb jmap --heap --pid 17573 | grep GC

产出:

垃圾-具有8个线程的首个(G1) GC

您可以在 JDK 14中使用以下 VM 参数,

-Xlog:gc -Xlog:gc*

日志是:

[0.008s][info][gc,heap] Heap region size: 1M
[0.008s][info][gc,heap,coops] Heap address: 0x0000000700000000, size: 4096 MB, Compressed Oops mode: Zero based, Oop shift amount: 3
[0.011s][info][gc           ] Using G1
[0.011s][info][gc,cds       ] Mark closed archive regions in map: [0x00000007bff00000, 0x00000007bff7aff8]
[0.011s][info][gc,cds       ] Mark open archive regions in map: [0x00000007bfe00000, 0x00000007bfe50ff8]
[0.027s][info][gc           ] Periodic GC disabled

为了实现性能目标,您需要检查各种 GC 算法。

Oracle JDK 中可用的收集器

- XX: + UseSerialGC

- XX: + UseParallelGC

- XX: + UseG1GC

- XX: + UseCONMarkSweepGC

- XX: UseZGC

在 Java7/8中打开 GC 日志记录

java -XX:+PrintGCDetails -XX:+PrintGCDateStamps - Xloggc: <file-path>

在 Java9和 Up 中打开 GC 日志记录

java –Xlog:gc*:file=<file-path>:filecount=10,filesize=10M

在 Java9和 Up 中动态打开 GC 日志记录

jcmd <pid> VM.log what=gc output=<file-path>

尝试使用 GC 日志分析工具来比较 GC 日志

气相色谱日志分析仪