java垃圾回收日志条目“Full GC (System)”是否意味着某个名为 System.gc() 的类?

2022-09-01 23:44:12

垃圾回收日志中的“完整 GC(系统)”条目是什么意思?那个叫做System.gc()的类?

我的垃圾回收日志有两种不同的“完整 gc”条目类型?一个带有“系统”一词,另一个没有。有什么区别?

(更新:我搜索了这个术语,没有找到明确的答案,只有几个问题。所以我想我会发布它)。

系统:

164638.058: [完整 GC (系统) [PSYoungGen: 22789K->0K(992448K)] [PSOldGen: 1645508K->1666990K(2097152K)] 1668298K->1666990K(3089600K) [PSPermGen: 164914K->164914K(166720K)], 5.7499132 秒] [倍数: user=5.69 sys=0.06, real=5.75 secs]

无系统:

166687.013: [完整GC [PSYoungGen: 126501K->0K(922048K)] [PSOldGen: 2063794K->1598637K(2097152K)] 2190295K->1598637K(3019200K) [PSPermGen: 165840K->164249K(166016K)],6.8204928秒] [倍数:用户=6.80 系统=0.02,real=6.81秒]

气相色谱选项

我们与 gc 相关的 java 内存选项是:-Xloggc:.。/server/pe/log/jvm_gc.log -XX:+PrintGCTimeStamps -XX:+PrintGCDetails

我们没有'-XX:+DisableExplicitGC',所以可能一些错误的类确实调用System.gc()

fwiw,我们完整的jvm选项:

-Xms3072m -Xmx3072m -XX:+HeapDumpOnOutOfMemoryError -XX:-UseGCOverheadLimit -Xloggc:../server/pe/log/jvm_gc.log -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -XX:MaxPermSize=256m -XX:+UseCompressedOops

提前致谢,


答案 1

从OpenJDK的来源,我会说它是

const bool is_system_gc = gc_cause == GCCause::_java_lang_system_gc;

// This is useful for debugging but don't change the output the
// the customer sees.
const char* gc_cause_str = "Full GC";
if (is_system_gc && PrintGCDetails) {
  gc_cause_str = "Full GC (System)";
}

我创建了一个自定义版本的 Runtime 类,以便在调用 Runtime.getRuntime().gc() 时将线程名称和堆栈跟踪记录到文件中。(System.gc() 调用它)我发现它在跟踪和删除此类呼叫者方面很有用。

发生这种情况的一个地方是在sun.misc.GC类中。RMI 将要求此类确保 GC 在最后 N 秒内一直执行。如果没有GC,它将触发完整的GC。

这只有在你减少次要指导性案例的数量时才会出现问题。具有讽刺意味的是,这可能意味着你会得到更完整的指导性案例。;)

我不使用RMI(也许JConsole除外),所以我把它设置为一周。(认为默认值为一小时)

-Dsun.rmi.dgc.server.gcInterval=604800000
-Dsun.rmi.dgc.client.gcInterval=604800000

答案 2

我在Mac上测试显式GC,使用jdk 1.6时它确实显示“Full GC(System)”,但使用jdk 1.7显示“Full GC”

因此,在调整GC日志时不要依赖“系统”标签,除非您确切地知道运行环境和jdk版本号