简短回答:JVM 命令行参数使用的所有内存大小都以传统的二进制单位指定,其中 1 千字节为 1024 字节,其他为 1024 的递增幂。
长答案:
This documentation page on the command line arguments 表示以下适用于所有接受内存大小的参数:
例如,要将大小设置为 8 GB,您可以指定 8g、8192m、8388608k 或 8589934592 作为参数。
对于-Xmx,给出了这些具体的例子:
以下示例展示了如何使用不同的单位将分配内存的最大允许大小设置为 80 MB:
-Xmx83886080
-Xmx81920k
-Xmx80m
在我想检查文档之前(我假设你已经有了?),我检查了 HotSpot 的源代码,发现内存值在 src/share/vm/runtime/arguments.cpp 中被函数 atomull 解析(这似乎代表“ASCII到内存中,unsigned long long"):
// Parses a memory size specification string.
static bool atomull(const char *s, julong* result) {
julong n = 0;
int args_read = sscanf(s, JULONG_FORMAT, &n);
if (args_read != 1) {
return false;
}
while (*s != '\0' && isdigit(*s)) {
s++;
}
// 4705540: illegal if more characters are found after the first non-digit
if (strlen(s) > 1) {
return false;
}
switch (*s) {
case 'T': case 't':
*result = n * G * K;
// Check for overflow.
if (*result/((julong)G * K) != n) return false;
return true;
case 'G': case 'g':
*result = n * G;
if (*result/G != n) return false;
return true;
case 'M': case 'm':
*result = n * M;
if (*result/M != n) return false;
return true;
case 'K': case 'k':
*result = n * K;
if (*result/K != n) return false;
return true;
case '\0':
*result = n;
return true;
default:
return false;
}
}
K、M、G 这些常量在src/share/vm/utilities/globalDefinitions.hpp 中定义:
const size_t K = 1024;
const size_t M = K*K;
const size_t G = M*K;
所有这些都证实了文档,除了对 TB 的 T 后缀的支持显然是后来添加的,根本没有记录。
不强制使用单位乘数,所以如果你想要十亿字节,你可以写-Xmx1000000000。如果你确实使用了乘数,它们是二进制的,所以-Xmx1G 表示 230 字节,或者一根内存条。
(这并不奇怪,因为 Java 早于 IEC 追溯重新定义现有单词的尝试。如果 IEC 仅建议使用限定符“二进制”和“十进制”来消除内存单元的歧义,则可以避免混淆有时它们的含义不清楚。例如,二进制千兆字节 (GB2) = 10243 字节,十进制千兆字节 (GB10) = 10003 字节。但是不,他们重新定义了每个人已经在使用的词,不可避免地引发混乱,让我们被这些小丑困住术语“gibibyte”、“tebibyte”等等。哦,上帝保佑我们。)