Java 11 默认垃圾回收器竟然不是 G1
Java JVM 大约 4877 字疑惑
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
阅读 1576 · 发布于 2023-06-08
————        END        ————
Give me a Star, Thanks:)
https://github.com/fendoudebb扫描下方二维码关注公众号和小程序↓↓↓

昵称:
随便看看
换一批
-
Redis 内存信息阅读 2391
-
Windows 子系统 Ubuntu 启动 Docker 报错解决方法阅读 5367
-
MySQL 字符串拼接阅读 3338
-
MySQL 之用户管理阅读 2233
-
Spring Boot 上传文件找不到临时目录阅读 10511
-
Linux 命令之设置和查看开机启动程序阅读 2256
-
SQL 删除重复记录且保留一条阅读 1563
-
macOS 打开 Java Mission Control 直接闪退解决方法阅读 654
-
Prometheus+Grafana+elasticsearch_exporter 监控 Elasticsearch阅读 1557
-
Nginx 负载均衡 WebSocket 请求阅读 2502