Максимальный размер кучи Java 32-разрядной JVM в 64-разрядной ОС
Вопрос не в максимальном размере кучи в 32-разрядной ОС, учитывая, что 32-разрядные операционные системы имеют максимальный размер адресуемой памяти 4 ГБ и что максимальный размер кучи JVM зависит от того, сколько непрерывной свободной памяти может быть зарезервировано.
Меня больше интересует максимальный (как теоретический, так и практически достижимый) размер кучи для 32-разрядной JVM, работающей в 64-разрядной ОС. В принципе, я смотрю на ответы, аналогичные цифрам в соответствующем вопросе на SO.
Что касается того, почему 32-разрядная JVM используется вместо 64-разрядной, причина не техническая, а скорее административная / бюрократическая - вероятно, уже слишком поздно устанавливать 64-разрядную JVM в производственной среде.
Переведено автоматически
Ответ 1
Вы можете запросить среду выполнения Java:
public class MaxMemory {
public static void main(String[] args) {
Runtime rt = Runtime.getRuntime();
long totalMem = rt.totalMemory();
long maxMem = rt.maxMemory();
long freeMem = rt.freeMemory();
double megs = 1048576.0;
System.out.println ("Total Memory: " + totalMem + " (" + (totalMem/megs) + " MiB)");
System.out.println ("Max Memory: " + maxMem + " (" + (maxMem/megs) + " MiB)");
System.out.println ("Free Memory: " + freeMem + " (" + (freeMem/megs) + " MiB)");
}
}
Это сообщит о "Максимальной памяти" на основе распределения кучи по умолчанию. Таким образом, вам все равно нужно будет поиграть с -Xmx
(на HotSpot). Я обнаружил, что под управлением 64-разрядной Windows 7 Enterprise моя 32-разрядная JVM HotSpot может выделять до 1577 МБАЙТ:
[C: scratch]> java -Xmx1600M MaxMemory
Произошла ошибка при инициализации виртуальной машины
Не удалось зарезервировать достаточно места для кучи объектов
Не удалось создать виртуальную машину Java.
[C: scratch]> java -Xmx1590M MaxMemory
Общий объем памяти: 2031616 (1.9375 Мбайт)
Максимальный объем памяти: 1654456320 (1577.8125 Мбайт)
Свободная память: 1840872 (1.75559234619 Мбайт)
[C: scratch]>
В то время как для 64-разрядной JVM в той же ОС, конечно, он намного выше (около 3TiB)
[C: scratch]> java -Xmx3560G MaxMemory
Произошла ошибка при инициализации виртуальной машины
Не удалось зарезервировать достаточно места для кучи объектов
[C: scratch]> java -Xmx3550G MaxMemory
Общий объем памяти: 94240768 (89,875 Мбайт)
Максимальный объем памяти: 3388252028928 (3184151.84297 Мбайт)
Свободная память: 93747752 (89.4048233032 Мбайт)
[C: scratch]>
Как уже упоминали другие, это зависит от операционной системы.
- Для 32-разрядной Windows: это будет <2 ГБ (в справочнике Windows internals указано, что 2 ГБ для пользовательских процессов)
- Для 32-разрядной BSD / Linux: <3 ГБ (из книги дьявола)
- Для 32-разрядной macOS X: <4 ГБ (из книги "Внутренние компоненты Mac OS X")
- Не уверен насчет 32-разрядной Solaris, но приведенный выше код был протестирован в этом ответе.
Для 64-разрядной хост-ОС, если JVM 32-разрядная, это все равно будет зависеть, скорее всего, как показано выше.
-- ОБНОВЛЕНИЕ 20110905: Я просто хотел указать на некоторые другие наблюдения / детали:
- Оборудование, на котором я запускал это, было 64-разрядным с установленным 6 ГБ оперативной памяти. Операционная система была Windows 7 Enterprise, 64-разрядная
- Фактический объем
Runtime.MaxMemory
, который может быть выделен, также зависит от рабочего набора операционной системы. Однажды я запустил это, когда у меня также был запущен VirtualBox, и обнаружил, что не могу не успешно запустить JVM HotSpot с-Xmx1590M
и пришлось уменьшить размер. Это также означает, что вы можете получить более 1590 МБ в зависимости от размера вашего рабочего набора на данный момент (хотя я по-прежнему утверждаю, что для 32-разрядной версии он будет меньше 2 ГБ из-за дизайна Windows)
Ответ 2
32-разрядные JVM, которые ожидают наличия одного большого фрагмента памяти и используют необработанные указатели, не могут использовать более 4 Гб (поскольку это 32-разрядное ограничение, которое также применяется к указателям). Сюда входят Sun и - я почти уверен - также реализации IBM. Я не знаю, есть ли, например, у JRockit или других вариантов с большим объемом памяти в их 32-разрядных реализациях.
Если вы ожидаете достижения этого предела, вам настоятельно следует рассмотреть возможность запуска параллельной проверки 64-разрядной JVM для вашей производственной среды, чтобы вы были готовы к выходу 32-разрядной среды из строя. В противном случае вам придется выполнять эту работу под давлением, что никогда не бывает приятным.
Редактировать 2014-05-15: Часто задаваемые вопросы о Oracle:
Максимальное теоретическое ограничение кучи для 32-разрядной JVM составляет 4G. Из-за различных дополнительных ограничений, таких как доступная подкачка, использование адресного пространства ядра, фрагментация памяти и накладные расходы виртуальной машины, на практике ограничение может быть намного ниже. В большинстве современных 32-разрядных систем Windows максимальный размер кучи будет варьироваться от 1,4G до 1,6G. В 32-разрядных ядрах Solaris адресное пространство ограничено 2G. В 64-разрядных операционных системах, работающих под управлением 32-разрядной виртуальной машины, максимальный размер кучи может быть выше, приближаясь к 4G во многих системах Solaris.
(http://www.oracle.com/technetwork/java/hotspotfaq-138619.html#gc_heap_32bit)
Ответ 3
Вы не указали, какую ОС.
В Windows (для моего приложения - приложения для управления рисками с длительной работой) мы заметили, что в 32-разрядной Windows мы не можем увеличить размер кучи не более 1280 МБ. Я сомневаюсь, что запуск 32-битной JVM под 64-битным управлением будет иметь какое-либо значение.
Мы портировали приложение на Linux и запускаем 32-разрядную JVM на 64-разрядном оборудовании, а виртуальная машина объемом 2,2 ГБ работает довольно легко.
Самая большая проблема, с которой вы можете столкнуться, - это GC в зависимости от того, для чего вы используете память.
Ответ 4
Из 4.1.2 Определение размера кучи:
"Для 32-разрядной модели процесса максимальный размер виртуального адреса процесса обычно составляет 4 ГБ, хотя некоторые операционные системы ограничивают его 2 или 3 ГБ. Максимальный размер кучи обычно составляет - Xmx3800m (1600m) для ограничений в 2 ГБ), хотя фактическое ограничение зависит от приложения. Для 64-разрядных моделей процессов максимальное значение практически не ограничено. "
Нашел здесь довольно хороший ответ: Максимальная память Java в Windows XP.