【问题标题】:find which type of garbage collector is running查找正在运行的垃圾收集器类型
【发布时间】:2011-02-17 04:06:51
【问题描述】:

Post JSE 5 人机工程学旨在为您自动选择适当类型的垃圾收集器(除其他外)。

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

【问题讨论】:

  • 对人体工程学特别是 GC 感到好奇,并希望在为生产提出建议之前看到它的实际应用;尝试了 jvisualvm,没有任何乐趣。

标签: java jvm


【解决方案1】:
java -XX:+PrintCommandLineFlags -version

将向您展示默认的垃圾收集器。我还发现以下页面很有用,details the default garbage collector for various operating systems

【讨论】:

  • 我在该命令的输出中没有看到与垃圾收集器相关的标志/信息。我在使用 Java 1.8.0_45 的 Windows 7 上。
  • @Zero3 好吧,你看到了什么做什么
  • 这显示了与 jvm 一起使用的命令行参数,但没有显示正在使用的垃圾收集器:[user@server ~]$ java -XX:+PrintCommandLineFlags -version -XX:InitialHeapSize=2018388928 -XX:MaxHeapSize=32210157568 -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) eric wang 的答案对我有用
  • 这里回答错误。不提供解决方案。
  • @liltitus27 您应该寻找可能的值:+UseParallelGC, +UseSerialGC, +UseConcMarkSweepGC, ...,请参阅 docs.oracle.com/javase/10/gctuning/… 我这个答案必须被接受为有效。
【解决方案2】:

(对于 Java )

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

jmap -heap <pid> | grep GC

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

例如

jmap -heap 26806 | grep GC

输出:

具有 8 个线程的并行 GC


@Update - 适用于 Java 9+

(感谢 @JakeRobb 的评论。)

自 Java 9 以来,有 2 处与此问题相关的更改:

  • 需要使用jhsdb 附加到Java 进程或启动调试器。
    参考:jhsdb
  • 默认gc改为G1

命令格式:

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

例如

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

输出:

具有 8 个线程的垃圾优先 (G1) GC

【讨论】:

  • 这应该是公认的答案。对于 Java 9 及更高版本,请使用 jhsdb jmap --heap --pid <pid> | grep GC
  • 如果有人像我一样遇到错误 - 支持的版本是 目标 VM 是 使用 jdk 安装目录运行上述命令,例如- /bin/jmap -heap | grep GC(当然适用于
  • 由于某种原因,我在 JDK 11 上运行此程序时出错。相反,jcmd <pid> VM.flags 报告了我正在寻找的 GC 信息。
【解决方案3】:
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

【讨论】:

    【解决方案4】:

    不是您问题的直接答案,但我相信这就是您要寻找的。​​p>

    根据Java 6 文档12(不仅仅是Java 5):

    参考1 说:

    在运行 服务器 VM,垃圾收集器 (GC) 与之前的连续剧不同 收集器 [...] 到并行收集器

    参考2 说:

    从 J2SE 5.0 开始,当一个 应用程序启动,启动器 可以尝试检测是否 应用程序正在运行 “服务器级”机器,如果是,请使用 Java HotSpot 服务器虚拟 机器(服务器虚拟机)而不是 Java HotSpot 客户端虚拟机 (客户端虚拟机)。

    另外,参考2 说:

    注意:对于 Java SE 6,定义 服务器级机器是一台具有 at 至少 2 个 CPU 和至少 2GB 物理内存。

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

    如果您进一步研究文档,您可能会为非服务器机器找到正确的答案。

    【讨论】:

    • 没错!但是你在虚拟机上试过吗?知道如果我为实例分配 1.75 个内核会发生什么吗?
    • 我没有,但我的第三个引用说“至少 2 个 CPU”,所以我猜它会使用串行 GC。关于您的评论“希望在实际中看到它 - 在为生产创建建议之前”,建议始终手动设置 GC。
    【解决方案5】:
    -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]
    

    这意味着 Parallel Garbage 收集器正在用于年轻代。 “分配失败”表示由于年轻代堆部分空间不足,垃圾回收开始。

    【讨论】:

    • 我觉得这个答案不完整。该打印输出的哪一部分表示并行收集器?另外,如何针对正在运行的 JVM 调用它?
    • PS 代表并行清理。 docs.oracle.com/javase/jp/8/docs/serviceabilityagent/sun/jvm/… 。您可以将这些参数传递给您启动的新 Java 进程,这意味着您不能将其应用于已经运行的进程。
    • 在这种情况下,我认为 Eric Wang 的答案更好,因为您可以针对正在运行的 JVM 调用它,并且因为它不假设您可以翻译不可能的通用缩写,例如“PS”。 ?
    【解决方案6】:

    您可以在 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
    

    【讨论】:

      【解决方案7】:

      【讨论】:

      • 嗯,这并不能真正为您提供正在使用的 GC。有趣的是,UseSerialGC、UseParallelOldGC、UseParallelGC、UseConcMarkSweepGC 的“getVMOption”输出都报告为“false”。
      • 抱歉,我应该在发帖前尝试一下 :-(。我以为我过去曾为此使用过它...
      • 这应该会为您提供可能针对 JVM 运行的 GC,通过查看 collectionCount 属性,您可以查看它们是否正在使用。
      【解决方案8】:

      这里有一些关于如何programmatically get GC info 的信息,但看起来它可能需要事先知道 GC 的名称。麻烦。

      编辑:尝试ManagementFactory.getGarbageCollectorMXBeans() 并遍历返回的列表。其中之一将处于活动状态。

      【讨论】:

        【解决方案9】:

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

        Oracle JDK 中的可用收集器

        -XX:+UseSerialGC

        -XX:+UseParallelGC

        -XX:+使用G1GC

        -XX:+UseConcMarkSweepGC

        -XX:使用ZGC

        在 Java 7 / 8 中开启 GC 日志记录

        java -XX:+PrintGCDetails -XX:+PrintGCDateStamps - Xloggc: &lt;file-path&gt;

        在 Java 9 及更高版本中开启 GC 日志记录

        java –Xlog:gc*:file=&lt;file-path&gt;:filecount=10,filesize=10M

        在 Java 9 及更高版本中动态开启 GC 日志记录

        jcmd &lt;pid&gt; VM.log what=gc output=&lt;file-path&gt;

        试用 GC Log 分析工具比较 GC 日志

        GC 日志分析器 - http://www.gcloganalyzer.com

        【讨论】:

          【解决方案10】:

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

          Tuning Garbage Collection with the 5.0 Java TM Virtual Machine

          另外,您可以使用JConsole 来监控垃圾收集。

          【讨论】:

          • 我知道你可以选择你的垃圾收集器,但是我感兴趣的是找出JVM为我选择了哪个收集器;谁知道呢,也许它甚至会根据使用情况即时改变策略!
          • @ryan-fernandes 来自 Garbage Collector Ergonomics,在运行服务器 VM 的服务器级机器上,默认 GC 是并行收集器,否则是串行收集器。
          猜你喜欢
          • 2011-08-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-02
          • 2011-05-14
          • 1970-01-01
          相关资源
          最近更新 更多