Java 11 默认垃圾回收器竟然不是 G1
Java JVM About 4,877 words疑惑
Java 9
之后JVM
的默认垃圾回收器就是G1
了,但今天在Kubernetes
容器Pod
中查看时发现用的竟然是SerialGC
。
查看命令行参数
可以看到默认的垃圾回收器竟然是SerialGC
串行化GC
。
java -XX:+PrintCommandLineFlags -version
输出
bash-4.4$ java -XX:+PrintCommandLineFlags -version
-XX:InitialHeapSize=215354880 -XX:MaxHeapSize=3445678080 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseSerialGC
openjdk version "11.0.16" 2022-07-19
OpenJDK Runtime Environment 18.9 (build 11.0.16+8)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.16+8, mixed mode, sharing)
查看操作系统指标
发现生效的CPU
个数只有1
个。
java -XshowSettings:system -version
输出
bash-4.4$ java -XshowSettings:system -version
Operating System Metrics:
Provider: cgroupv1
Effective CPU Count: 1
CPU Period: 100000us
CPU Quota: -1
CPU Shares: 2us
List of Processors, 4 total:
0 1 2 3
List of Effective Processors, 4 total:
0 1 2 3
List of Memory Nodes, 1 total:
0
List of Available Memory Nodes, 1 total:
0
Memory Limit: 12.84G
Memory Soft Limit: Unlimited
Memory & Swap Limit: Unlimited
openjdk version "11.0.16" 2022-07-19
OpenJDK Runtime Environment 18.9 (build 11.0.16+8)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.16+8, mixed mode, sharing)
查看 JVM 参数默认值
bash-4.4$ java -XX:+PrintFlagsFinal -version | grep GC
bool UseConcMarkSweepGC = false {product} {default}
bool UseG1GC = false {product} {default}
bool UseParallelGC = false {product} {default}
bool UseParallelOldGC = false {product} {default}
bool UseSerialGC = true {product} {ergonomic}
openjdk version "11.0.16" 2022-07-19
OpenJDK Runtime Environment 18.9 (build 11.0.16+8)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.16+8, mixed mode, sharing)
原因
{ergonomic}
指的是该标志会自动设置,取决于可用的CPU
处理器和内存大小。
Java 10
中当机器有2
个可用的处理器和2GB
内存时,将JVM
认为是服务器模式,可以使用-XX:+AlwaysActAsServerClassMachine
打开Server
模式,或者-XX:+NeverActAsServerClassMachine
关闭Server
模式。
Server
模式时选择G1GC
,Client
模式时选择SerialGC
。
JVM 源码
判断是否是Server
机器
// This is the working definition of a server class machine:
// >= 2 physical CPU's and >=2GB of memory, with some fuzz
// because the graphics memory (?) sometimes masks physical memory.
// If you want to change the definition of a server class machine
// on some OS or platform, e.g., >=4GB on Windows platforms,
// then you'll have to parameterize this method based on that state,
// as was done for logical processors here, or replicate and
// specialize this method for each platform. (Or fix os to have
// some inheritance structure and use subclassing. Sigh.)
// If you want some platform to always or never behave as a server
// class machine, change the setting of AlwaysActAsServerClassMachine
// and NeverActAsServerClassMachine in globals*.hpp.
bool os::is_server_class_machine() {
// First check for the early returns
if (NeverActAsServerClassMachine) {
return false;
}
if (AlwaysActAsServerClassMachine) {
return true;
}
// Then actually look at the machine
bool result = false;
const unsigned int server_processors = 2;
const julong server_memory = 2UL * G;
// We seem not to get our full complement of memory.
// We allow some part (1/8?) of the memory to be "missing",
// based on the sizes of DIMMs, and maybe graphics cards.
const julong missing_memory = 256UL * M;
/* Is this a server class machine? */
if ((os::active_processor_count() >= (int)server_processors) &&
(os::physical_memory() >= (server_memory - missing_memory))) {
const unsigned int logical_processors =
VM_Version::logical_processors_per_package();
if (logical_processors > 1) {
const unsigned int physical_packages =
os::active_processor_count() / logical_processors;
if (physical_packages >= server_processors) {
result = true;
}
} else {
result = true;
}
}
return result;
}
选择GC
参数
void GCArguments::select_gc_ergonomically() {
#if INCLUDE_ALL_GCS
if (os::is_server_class_machine()) {
FLAG_SET_ERGO_IF_DEFAULT(bool, UseG1GC, true);
} else {
FLAG_SET_ERGO_IF_DEFAULT(bool, UseSerialGC, true);
}
#else
UNSUPPORTED_OPTION(UseG1GC);
UNSUPPORTED_OPTION(UseParallelGC);
UNSUPPORTED_OPTION(UseParallelOldGC);
UNSUPPORTED_OPTION(UseConcMarkSweepGC);
FLAG_SET_ERGO_IF_DEFAULT(bool, UseSerialGC, true);
#endif // INCLUDE_ALL_GCS
}
参考链接
https://stackoverflow.com/questions/52474162/why-is-serialgc-chosen-over-g1gc
Views: 5,526 · Posted: 2023-06-08
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb/LiteNote扫描下方二维码关注公众号和小程序↓↓↓
Loading...