java垃圾回收日志条目是否“Full GC(系统)"?意思是一些名为 System.gc() 的类?

2022-01-16 00:00:00 garbage-collection java

垃圾收集日志中的Full GC (System)"条目是什么意思?那个叫 System.gc() 的类?

What does "Full GC (System)" entry in the garbage collection logs mean? That some class called System.gc() ?

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

My garbage collection logs has two different entry types for 'full gc'? One with the word 'System', the other without. What's the difference?

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

(Update: I searched on this term and didn't find a definitive answer, only a few questions. So I thought I'd post it).

系统:

164638.058:[Full GC (系统) [PSYoungGen:22789K->0K(992448K)][PSOldGen:1645508K->1666990K(2097152K)]1668298K->1666990K(3089600K)[PSPermGen:164914K->164914K(166720K)], 5.7499132秒] [时间:用户=5.69 系统=0.06,真实=5.75 秒]

164638.058: [Full GC (System) [PSYoungGen: 22789K->0K(992448K)] [PSOldGen: 1645508K->1666990K(2097152K)] 1668298K->1666990K(3089600K) [PSPermGen: 164914K->164914K(166720K)], 5.7499132 secs] [Times: 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,真实=6.81 秒]

166687.013: [Full GC [PSYoungGen: 126501K->0K(922048K)] [PSOldGen: 2063794K->1598637K(2097152K)] 2190295K->1598637K(3019200K) [PSPermGen: 165840K->164249K(166016K)], 6.8204928 secs] [Times: user=6.80 sys=0.02, real=6.81 secs]

GC 选项

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

Our gc-related java memory options are: -Xloggc:../server/pe/log/jvm_gc.log -XX:+PrintGCTimeStamps -XX:+PrintGCDetails

我们不使用'-XX:+DisableExplicitGC',所以可能某些错误的类确实调用了 System.gc()

We do not '-XX:+DisableExplicitGC', so it's possible some errant class does call System.gc()

fwiw,我们完整的 jvm 选项:

fwiw, our full jvm options:

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

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

提前致谢,

推荐答案

从 OpenJDK 的源代码我会说是

From the source for OpenJDK I would say it is

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() 调用它)我发现它在跟踪和删除此类调用者方面很有用.

I created a custom version of the Runtime class to record the thread name and stack trace to a file whenever Runtime.getRuntime().gc() was called. (System.gc() calls this) I found it useful in tracking down and removing such callers.

发生这种情况的一个地方是 sun.misc.GC 类.RMI 将要求该类确保在最后 N 秒内执行了 GC.如果没有 GC,则会触发 full GC.

One place this happens is in sun.misc.GC class. The RMI will ask this class to ensure a GC has been performing in the last N seconds. If there has been no GC it triggers a full GC.

这仅在您减少次要 GC 的数量时才会显示为问题.具有讽刺意味的是,这可能意味着您获得更多完整的 GC.;)

This only shows as a problem if you reduce the number of minor GCs. Ironicly it can mean you get more full GCs. ;)

我不使用 RMI(也许 JConsole 除外)所以我将它设置为一周.(认为​​默认是一个小时)

I don't use RMI (except perhaps JConsole) So I have it set to a week. (Think the default is an hour)

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

相关文章