默认垃圾收集器 Hotspot JVM 11/17 的标准
Criteria for default garbage collector Hotspot JVM 11/17
我发现 source 描述使用的默认 gc 会根据可用资源而变化。似乎 jvm 在硬件和 os.
上使用 g1gc 或串行 gc dependnig
The serial collector is selected by default on certain hardware and operating system configurations
有人可以指出更详细的来源,说明具体标准是什么以及如何在 dockerized/kubernetes 环境中应用。
换句话说:
可以将k8s中pod的资源请求设置为eg。 1500 mCpu 使 jvm 使用串行 gc 并更改为 2 Cpu 将默认 gc 更改为 g1gc?何时使用哪个 gc 的限制是否会根据 jvm 版本(11 对 17)而变化?
在JDK 11 和17 Serial
收集器只有一个CPU 可用时使用。否则选择G1
如果您限制容器可用的 CPUS 数量,JVM 选择 Serial
而不是默认值 G1
JDK11
1 CPU
docker run --cpus=1 --rm -it eclipse-temurin:11 java -Xlog:gc* -version
[0.004s][info][gc] Using **Serial**
它使用Serial
不止一个CPU
docker run --cpus=2 --rm -it eclipse-temurin:11 java -Xlog:gc* -version
[0.008s][info][gc ] Using G1
它使用G1
JDK17
1 CPU
docker run --cpus=1 --rm -it eclipse-temurin:17 java -Xlog:gc* -version
[0.004s][info][gc] Using Serial
它使用Serial
不止一个CPU
docker run --cpus=2 --rm -it eclipse-temurin:17 java -Xlog:gc* -version
[0.007s][info][gc] Using G1
它使用G1
在当前的 OpenJDK 中,“服务器 class 机器”默认选择 G1 GC,否则为串行 GC。 “服务器 class 机器”定义为具有 2 个或更多非 HT CPU 和 2 个或更多 GiB RAM 的系统。
具体算法见src/hotspot/share/runtime/os.cpp:
// 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;
}
我发现 source 描述使用的默认 gc 会根据可用资源而变化。似乎 jvm 在硬件和 os.
上使用 g1gc 或串行 gc dependnigThe serial collector is selected by default on certain hardware and operating system configurations
有人可以指出更详细的来源,说明具体标准是什么以及如何在 dockerized/kubernetes 环境中应用。 换句话说:
可以将k8s中pod的资源请求设置为eg。 1500 mCpu 使 jvm 使用串行 gc 并更改为 2 Cpu 将默认 gc 更改为 g1gc?何时使用哪个 gc 的限制是否会根据 jvm 版本(11 对 17)而变化?
在JDK 11 和17 Serial
收集器只有一个CPU 可用时使用。否则选择G1
如果您限制容器可用的 CPUS 数量,JVM 选择 Serial
而不是默认值 G1
JDK11
1 CPU
docker run --cpus=1 --rm -it eclipse-temurin:11 java -Xlog:gc* -version
[0.004s][info][gc] Using **Serial**
它使用Serial
不止一个CPU
docker run --cpus=2 --rm -it eclipse-temurin:11 java -Xlog:gc* -version
[0.008s][info][gc ] Using G1
它使用G1
JDK17
1 CPU
docker run --cpus=1 --rm -it eclipse-temurin:17 java -Xlog:gc* -version
[0.004s][info][gc] Using Serial
它使用Serial
不止一个CPU
docker run --cpus=2 --rm -it eclipse-temurin:17 java -Xlog:gc* -version
[0.007s][info][gc] Using G1
它使用G1
在当前的 OpenJDK 中,“服务器 class 机器”默认选择 G1 GC,否则为串行 GC。 “服务器 class 机器”定义为具有 2 个或更多非 HT CPU 和 2 个或更多 GiB RAM 的系统。
具体算法见src/hotspot/share/runtime/os.cpp:
// 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;
}