Ответ 1
Короткий ответ: все размеры памяти, используемые аргументами командной строки JVM, указаны в традиционных двоичных единицах, где килобайт равен 1024 байтам, а остальные - мощности 1024.
Длинный ответ:
Эта страница документации в аргументах командной строки говорит, что для всех аргументов, принимающих размеры памяти, применяется следующее:
Например, чтобы установить размер до 8 ГБ, в качестве аргумента можно указать либо
8g
,8192m
,8388608k
, либо8589934592
.
Для -Xmx
он дает следующие конкретные примеры:
В следующих примерах показано, как установить максимальный разрешенный размер выделенной памяти на 80 МБ с использованием различных единиц:
-Xmx83886080
-Xmx81920k
-Xmx80m
Прежде чем я подумал проверить документацию (предположил, что у вас уже есть?), я проверил источник HotSpot и обнаружил, что значения памяти анализируются в src/share/vm/runtime/arguments.cpp с помощью функции atomull
(которая, как представляется, означает "ASCII в память, без знака длинный" ):
// 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;
Все это подтверждает документацию, за исключением того, что поддержка суффикса T
для терабайт, по-видимому, была добавлена позже и вообще не документирована.
Не обязательно использовать единичный множитель, поэтому, если вы хотите один миллиард байт, вы можете написать -Xmx1000000000
. Если вы используете множитель, они двоичные, поэтому -Xmx1G
означает 2 30 байт или одну палку o 'RAM.
(что не удивительно, потому что Java предшествует попытке IEC ретроактивно переопределять существующие слова. Путаница могла быть сохранена, если бы МЭК просто советовал устранить неоднозначность блоков памяти с помощью "двоичных" и "десятичных" классификаторов, например, двоичные гигабайты (GB 2) = 1024 3 а десятичные гигабайты (GB 10) = 1000 3. Но нет, они переопределили слова, которые все уже использовали, неизбежно взорвали путаницу и оставили нас застрявшими с этими клоунскими терминами "гиббите", "тебибите" и остальным. запасьте нас.)