为什么选择SerialGC而不是G1GC?

时间:2018-09-24 07:03:10

标签: java garbage-collection jvm

我在非常相似的VM上运行Java,但在某种情况下我找不到解释为什么选择SerialGC而不是G1GC的解释。它在AWS上具有相同的Java版本,相同的操作系统,相同的VM实例类型,我怀疑唯一的区别是容器设置,但我不知道如何查明哪些更改。有没有办法解释为什么VM决定选择此设置还是其他?

两种情况下的Java版本:

java version "10.0.1" 2018-04-17 Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10) Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)

在一种情况下运行Java:

java -XX:+PrintFlagsFinal -XX:+PrintCommandLineFlag

输出:

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8 -XX:InitialHeapSize=253366976 -XX:MaxHeapSize=4053871616 -XX:+PrintCommandLineFlags -XX:+PrintFlagsFinal -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseSerialGC [Global flags] (...) bool UseG1GC = false {product} {default} bool UseParallelGC = false {product} {default} bool UseSerialGC = true {product} {ergonomic}

另一个:

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF8 -XX:G1ConcRefinementThreads=8 -XX:InitialHeapSize=253480064 -XX:MaxHeapSize=4055681024 -XX:+PrintCommandLineFlags -XX:+PrintFlagsFinal -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC [Global flags] (...) bool UseG1GC = true {product} {ergonomic} bool UseParallelGC = false {product} {default} bool UseSerialGC = false {product} {default}

1 个答案:

答案 0 :(得分:3)

{ergonomic}中的

-XX:+PrintFlagsFinal表示该标志是根据可用处理器的数量和RAM的数量自动设置的。

JDK 10 treats machine as "server"(如果它具有至少2个可用CPU和2 GB RAM)。这可以被覆盖 -XX:+AlwaysActAsServerClassMachine-XX:+NeverActAsServerClassMachine JVM标志。

“服务器”配置假定G1 as the default GC,而“客户端”计算机默认使用SerialGC

要计算可用处理器的数量,JDK不仅使用OS中可见的CPU,还使用处理器亲和力和cgroup限制,包括

  • cpu.shares
  • cpu.cfs_quota_us
  • cpuset.cpus

由于您是在容器中运行Java,因此容器可能会施加cgroup限制,从而导致可用CPU数量或内存量减少。使用-Xlog:os+container=trace查找每个特定环境中的有效限制。