考虑以下命令行
java -Xms128m -Xms256m myapp.jar
JVM最小内存设置(Xms
选项)会应用哪个值:128m还是256m?
考虑以下命令行
java -Xms128m -Xms256m myapp.jar
JVM最小内存设置(Xms
选项)会应用哪个值:128m还是256m?
一如既往,要检查您本地JVM的具体实现,但这里有一个快速的方法可以在命令行上检查,而无需编写代码。
> java -version; java -Xmx1G -XX:+PrintFlagsFinal -Xmx2G 2>/dev/null | grep MaxHeapSize
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
uintx MaxHeapSize := 2147483648 {product}
所以在这种情况下,参数的第二个实例(2G)优先考虑(至少在1.8版本中是如此),我在大多数其他现代版本中也有相同的经验。
java -Xmx1G -XX:+PrintFlagsFinal -Xmx2G 2>/dev/null | grep MaxHeapSize
能够更轻松地推断出最大堆大小。该命令会打印Java虚拟机的配置信息,其中包括最大堆大小的信息,并使用grep命令筛选出包含"MaxHeapSize"关键词的行。 - ryenusIBM JVM将参数列表中最右边的实例视为优先。关于HotSpot等其他JVM,我无法发表评论。
我们这样做是因为通常会有来自批处理文件的嵌套命令行,人们只能在末尾添加,并希望使其成为优先。
顺便说一句,OpenJDK 1.7看起来也是采取最右边的值,至少对于-Xms参数是这样。
取决于JVM,也许还取决于版本...甚至也可能取决于您桌子上有多少回形针。 它可能根本无法工作。 不要这样做。
如果出于某些原因超出了您的控制,请按照启动jar包的方式编译和运行此程序。但是请注意,依赖选项顺序是一个非常糟糕的主意。
public class TotalMemory
{
public static void main(String[] args)
{
System.out.println("Total Memory: "+Runtime.getRuntime().totalMemory());
System.out.println("Free Memory: "+Runtime.getRuntime().freeMemory());
}
}
JVM最小内存应该设置哪些参数?
在下面列出的各种Java版本中,参数列表中最右边的值将被视为“获胜者”。正如其他人所指出的那样,依赖此方法可能不是一个好主意,但也许这些信息仍然是有用的。
Java 1.8.0_172
~ $ java8
java version "1.8.0_172"
Java(TM) SE Runtime Environment (build 1.8.0_172-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.172-b11, mixed mode)
~ $ java -Xmx1024m -Xmx4024m -XX:+PrintFlagsFinal Test 2>/dev/null | grep MaxHeapSize
uintx MaxHeapSize := 4219469824 {product}
Java 11.0.3
~ $ java11
java version "11.0.3" 2019-04-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.3+12-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.3+12-LTS, mixed mode)
~ $ java -Xmx1024m -Xmx4024m -XX:+PrintFlagsFinal Test 2>/dev/null | grep MaxHeapSize
size_t MaxHeapSize = 4219469824 {product} {command line}
OpenJDK 12.0.1
~ $ java12
openjdk version "12.0.1" 2019-04-16
OpenJDK Runtime Environment (build 12.0.1+12)
OpenJDK 64-Bit Server VM (build 12.0.1+12, mixed mode, sharing)
~ $ java -Xmx1024m -Xmx4024m -XX:+PrintFlagsFinal Test 2>/dev/null | grep MaxHeapSize
size_t MaxHeapSize = 4219469824 {product} {command line}
AdoptOpenJDK 12.0.1
~ $ java12a
openjdk version "12.0.1" 2019-04-16
OpenJDK Runtime Environment AdoptOpenJDK (build 12.0.1+12)
OpenJDK 64-Bit Server VM AdoptOpenJDK (build 12.0.1+12, mixed mode, sharing)
~ $ java -Xmx1024m -Xmx4024m -XX:+PrintFlagsFinal Test 2>/dev/null | grep MaxHeapSize
size_t MaxHeapSize = 4219469824 {product} {command line}
OpenJDK 13-ea
:这是OpenJDK项目的一个版本,编号为13-ea。~ $ java13
openjdk version "13-ea" 2019-09-17
OpenJDK Runtime Environment (build 13-ea+22)
OpenJDK 64-Bit Server VM (build 13-ea+22, mixed mode, sharing)
~ $ java -Xmx1024m -Xmx4024m -XX:+PrintFlagsFinal Test 2>/dev/null | grep MaxHeapSize
size_t MaxHeapSize = 4219469824 {product} {command line}
我打赌是第二个。通常情况下,参数的处理顺序如下:
for( int i=0; i<argc; i++ ) {
process_argument(argv[i]);
}
不过,如果我正在编写 Java 参数解析器,我会抱怨冲突的参数。
我的实验表明它取最大值xmx
。
因此,如果你传入-xmx4g -xmx1g
,它将取4g
,
如果你传入-xmx1g -xmx4g
,它仍然会取4g
。
java -version; java -Xmx2G -Xmx1G -XX:+PrintFlagsFinal 2>/dev/null | grep MaxHeapSize
。 - Adrian Baker