我在Kubernetes中有大约112 GB内存的容器。其中部署了一个java应用程序(Spring Boot)。打印参数显示了这一点
...Application - -server -Dspring.profiles.active=prod -Xms110g -Xmx110g
JVM的输出显示只有36GB的堆可用于进程。
private static final long GIGABYTE = 1024L * 1024L * 1024L;
public static float bytesToGigabytes(long bytes) {
return Math.floorDiv(bytes / GIGABYTE, 3);
}
public void getMemUsed() {
// Get the Java runtime
Runtime runtime = Runtime.getRuntime();
// Run the garbage collector
runtime.gc();
// Calculate the used memory
long memory = runtime.totalMemory() - runtime.freeMemory();
log.info("RAM Used %.3fGb of %.3fGb (max %.3fGb)".formatted(
bytesToGigabytes(memory), bytesToGigabytes(runtime.totalMemory()), bytesToGigabytes(runtime.maxMemory())));
}
印刷品
RAM Used 0.000Gb of 36.000Gb
...
RAM Used 29.000Gb of 36.000Gb
而像“heap”和“jps”这样的工具则展示了另一幅画面
free -h
total used free shared buff/cache available
Mem: 125Gi 102Gi 15Gi 118Mi 8.3Gi 22Gi
Swap: 0B 0B 0B
top shell命令输出
PS:当内存增长到33-35 GB以上时,pod会重新启动
可能与此Linux有关:由于虚拟内存限制,无法在单个进程中分配超过32 GB/64 GB的内存
解决。只需添加此 JVM 参数
-XX:+UseContainerSupport -XX:MaxRAMPercentage=100
并将内存计算功能更改为
log.info("RAM used {} of {} (max {})", FileUtils.byteCountToDisplaySize(memory),
FileUtils.byteCountToDisplaySize(runtime.totalMemory()),
FileUtils.byteCountToDisplaySize(runtime.maxMemory()));