【发布时间】:2011-02-17 04:06:51
【问题描述】:
Post JSE 5 人机工程学旨在为您自动选择适当类型的垃圾收集器(除其他外)。
我想知道是否有任何方法可以确认/了解垃圾收集器的类型以及 JVM 人体工程学选择/当前设置的性能目标。
【问题讨论】:
-
对人体工程学特别是 GC 感到好奇,并希望在为生产提出建议之前看到它的实际应用;尝试了 jvisualvm,没有任何乐趣。
Post JSE 5 人机工程学旨在为您自动选择适当类型的垃圾收集器(除其他外)。
我想知道是否有任何方法可以确认/了解垃圾收集器的类型以及 JVM 人体工程学选择/当前设置的性能目标。
【问题讨论】:
java -XX:+PrintCommandLineFlags -version
将向您展示默认的垃圾收集器。我还发现以下页面很有用,details the default garbage collector for various operating systems。
【讨论】:
[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 的答案对我有用
(对于 Java )
此命令打印正在运行的 JVM 的 GC 类型:
jmap -heap <pid> | grep GC
对于现代计算机(多 CPU、大内存),JVM 会将其检测为服务器机器,并默认使用 Parallel GC,除非您通过 JVM 标志明确指定要使用的 gc。
例如
jmap -heap 26806 | grep GC
输出:
具有 8 个线程的并行 GC
(感谢 @JakeRobb 的评论。)
自 Java 9 以来,有 2 处与此问题相关的更改:
jhsdb 附加到Java 进程或启动调试器。G1。命令格式:
jhsdb jmap --heap --pid <pid> | grep GC
例如
jhsdb jmap --heap --pid 17573 | grep GC
输出:
具有 8 个线程的垃圾优先 (G1) GC
【讨论】:
jhsdb jmap --heap --pid <pid> | grep GC。
jcmd <pid> VM.flags 报告了我正在寻找的 GC 信息。
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
【讨论】:
不是您问题的直接答案,但我相信这就是您要寻找的。p>
参考1 说:
在运行 服务器 VM,垃圾收集器 (GC) 与之前的连续剧不同 收集器 [...] 到并行收集器
参考2 说:
从 J2SE 5.0 开始,当一个 应用程序启动,启动器 可以尝试检测是否 应用程序正在运行 “服务器级”机器,如果是,请使用 Java HotSpot 服务器虚拟 机器(服务器虚拟机)而不是 Java HotSpot 客户端虚拟机 (客户端虚拟机)。
另外,参考2 说:
注意:对于 Java SE 6,定义 服务器级机器是一台具有 at 至少 2 个 CPU 和至少 2GB 物理内存。
从这些信息中,您可以知道如果盒子是服务器(根据2),那么它将使用并行 GC。你也可以推断它在运行时不会改变GC。
如果您进一步研究文档,您可能会为非服务器机器找到正确的答案。
【讨论】:
-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 收集器正在用于年轻代。 “分配失败”表示由于年轻代堆部分空间不足,垃圾回收开始。
【讨论】:
您可以在 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
【讨论】:
【讨论】:
这里有一些关于如何programmatically get GC info 的信息,但看起来它可能需要事先知道 GC 的名称。麻烦。
编辑:尝试ManagementFactory.getGarbageCollectorMXBeans() 并遍历返回的列表。其中之一将处于活动状态。
【讨论】:
要实现性能目标,您需要检查各种 GC 算法。
Oracle JDK 中的可用收集器
-XX:+UseSerialGC
-XX:+UseParallelGC
-XX:+使用G1GC
-XX:+UseConcMarkSweepGC
-XX:使用ZGC
在 Java 7 / 8 中开启 GC 日志记录
java -XX:+PrintGCDetails -XX:+PrintGCDateStamps - Xloggc: <file-path>
在 Java 9 及更高版本中开启 GC 日志记录
java –Xlog:gc*:file=<file-path>:filecount=10,filesize=10M
在 Java 9 及更高版本中动态开启 GC 日志记录
jcmd <pid> VM.log what=gc output=<file-path>
试用 GC Log 分析工具比较 GC 日志
GC 日志分析器 - http://www.gcloganalyzer.com
【讨论】:
您可以使用 JRE 的 -XX 标志来选择您选择的垃圾收集器。
Tuning Garbage Collection with the 5.0 Java TM Virtual Machine
另外,您可以使用JConsole 来监控垃圾收集。
【讨论】: