引言
本文主要是讲解 InitialRAMPercentage、MinRAMPercentage, MaxRAMPercentage 三个 JVM 参数之间的区别。参数由 Java 8 update 191 引入,主要是用于配置运行在物理机或者容器中的 Java 应用堆内存大小。
InitialRAMPercentage
-XX:InitialRAMPercentage
用于配置堆的初始化大小。假如物理机或者容器的内存大小(limit 限制)为 1 GB, -XX:InitialRAMPercentage=25
,那么堆内存大小大概为 250 MB(1 GB 的 25%)。
当 -Xms
参数未指定时,-XX:InitialRAMPercentage
用于配置堆的初始化大小。如果指定了 -Xms
,-XX:InitialRAMPercentage
将会被 JVM 忽略。
MaxRAMPercentage、MinRAMPercentage
以上两个参数主要用于配置堆的最大内存大小(JDK 的开发团队起的名字 -XX:MinRAMPercentage
很容易让人理解为是堆的最小内存大小,然而并不是)。
如果你的物理机(或容器)内存小于 250 MB(大约),那么 -XX:MinRAMPercentage
参数用于配置应用堆的最大内存大小。假如物理机内存大小为 100MB,-XX:MinRAMPercentage=50
,那么应用的最大堆内存大小为 50 MB。
当你的物理机(或容器)的内存大于 250 MB(大约),-XX:MaxRAMPercentage
参数将用于配置应用堆的最大内存大小。
我们举两个例子来验证以上结论:
例 1:较小的宿主机内存
我们把容器的内存限制为 100 MB,MaxRAMPercentage 配置为 25, MinRAMPercentage 配置为 50。那么由于宿主机的内存 100 MB 小于 250 MB,所以后者的配置应该生效,也就是如图所示,应用的最大堆大小为 48.38 MB(100 MB 的 50%)。从该例子中看出MaxRAMPercentage
被忽略。
1 | docker run -m 100MB openjdk:10 java -XX:MaxRAMPercentage=25 -XX:MinRAMPercentage=50 -XshowSettings:vm -version |
例 2:较大的宿主机内存
我们把容器的内存限制改为 1 GB,MaxRAMPercentage 配置为 25, MinRAMPercentage 配置为 50。我们看到实际的应用堆最大大小为 247.50 MB(由于宿主机内存大于 250 MB,所以前者配置生效)。
1 | docker run -m 1GB openjdk:10 java -XX:MaxRAMPercentage=25 -XX:MinRAMPercentage=50 -XshowSettings:vm -version |
当 -Xmx
未指定时,-XX:MaxRAMPercentage
及 -XX:MinRAMPercentage
用于配置堆的最大内存大小。如果 -Xmx
指定了,那么以上两个参数将会被 JVM 忽略。如图:
1 | docker run -m 1GB openjdk:10 java -XX:MaxRAMPercentage=25 -XX:MinRAMPercentage=25 -Xmx512m -XshowSettings:vm -version |
-Xmx512m
、-XX:MaxRAMPercentage=25
、-XX:MinRAMPercentage=25
同时指定了,但是只有 -Xmx512m
起到了作用。
结论
- 用
-XX:InitialRAMPercentage
配置你的应用堆初始化内存大小(前提是-Xms
未配置)。 -XX:MinRAMPercentage
、-XX:MaxRAMPercentage
用于配置最大堆大小(前提是-Xmx
未配置)。-XX:MaxRAMPercentage
应用于大多场景,毕竟主流的企业级 Java 应用内存已经超过了 250 MB。除非构建的是微型应用,物理机内存小于 250 MB,你才需要使用-XX:MinRAMPercentage
。