Мне всегда удавалось выделить 1400 мегабайт для Java SE, работающей в 32-разрядной Windows XP (Java 1.4, 1.5 и 1.6).
java -Xmx1400m ...
Сегодня я попробовал тот же вариант на новом компьютере с Windows XP, используя Java 1.5_16 и 1.6.0_07, и получил сообщение об ошибке:
Error occurred during initialization of VM Could not reserve enough space for object heap Could not create the Java virtual machine.
Методом проб и ошибок кажется, что 1200 мегабайт - это максимум, что я могу выделить на этой машине.
Есть идеи, почему одна машина допускает 1400, а другая только 1200?
Редактировать: На компьютере установлено 4 ГБ оперативной памяти и около 3,5 ГБ, которые Windows может распознать.
Переведено автоматически
Ответ 1
Имейте в виду, что в Windows реализовано управление виртуальной памятью, и JVM требуется только непрерывная память в ее адресном пространстве. Итак, другие программы, запущенные в системе, не обязательно должны влиять на размер вашей кучи. Что вам помешает, так это библиотеки DLL, которые загружаются в ваше адресное пространство. К сожалению, оптимизации в Windows, которые сводят к минимуму перемещение DLL-файлов во время компоновки, повышают вероятность того, что у вас будет фрагментированное адресное пространство. Помимо обычных вещей, которые могут сократить ваше адресное пространство, к ним относятся программы безопасности, CBT-программы, шпионские программы и другие формы вредоносного ПО. Вероятными причинами различий являются различные исправления безопасности, версии среды выполнения C и т.д. Драйверы устройств и другие компоненты ядра имеют свое собственное адресное пространство (остальные 2 ГБ из 4 ГБ 32-разрядного пространства).
Вы могли бы попробовать просмотреть привязки ваших DLL-файлов в вашем процессе JVM и попробовать переместить ваши DLL-файлы в более компактное адресное пространство. Не весело, но если вы в отчаянии...
В качестве альтернативы вы можете просто переключиться на 64-разрядную Windows и 64-разрядную JVM. Несмотря на то, что предлагали другие, хотя это будет потреблять больше оперативной памяти, у вас будет намного больше непрерывного виртуального адресного пространства, и выделение 2 ГБ непрерывно было бы тривиальным.
Причина, по которой нам нужна непрерывная область памяти для кучи, заключается в том, что у нас есть куча побочных структур данных, которые индексируются (масштабируются) смещениями от начала кучи. Например, мы отслеживаем обновления ссылок на объекты с помощью "массива меток карт", в котором по одному байту на каждые 512 байт кучи. Когда мы храним ссылку в куче, мы должны отметить соответствующий байт в массиве меток карт. Мы сдвигаем адрес назначения хранилища вправо и используем его для индексации массива карточек. Забавные арифметические игры с адресацией, которые вы не можете делать на Java, в которые вы можете (должны :-) играть на C ++.
Обычно у нас не возникает проблем с получением небольших смежных областей (примерно до 1,5 ГБ в Windohs, примерно до 3,8 ГБ в Solaris. YMMV.). В Windohs проблема в основном в том, что некоторые библиотеки, которые загружаются перед запуском JVM, разбивают адресное пространство. Использование параметра / 3GB не приведет к перебазированию этих библиотек, поэтому они по-прежнему являются для нас проблемой.
Мы знаем, как создавать фрагментированные кучи, но их использование сопряжено с некоторыми накладными расходами. У нас больше запросов на более быстрое управление хранилищем, чем на большие кучи в 32-разрядной JVM. Если вам действительно нужны большие кучи, переключитесь на 64-разрядную JVM. Нам по-прежнему нужна непрерывная память, но ее гораздо проще получить в 64-разрядном адресном пространстве.
Ответ 3
Ограничения по размеру кучи Java для Windows следующие:
максимально возможный размер кучи на 32-разрядной Java: 1,8 ГБ
рекомендуемый размер кучи для 32-разрядной Java: 1,5 ГБ (или 1,8 ГБ с опцией / 3 ГБ)
Это не поможет вам увеличить кучу Java, но теперь вы знаете, что не можете выйти за пределы этих значений.
Ответ 4
Oracle JRockit, который может обрабатывать несмежную кучу, может иметь размер кучи Java 2,85 ГБ в Windows 2003 / XP с переключателем /3GB. Похоже, что фрагментация может оказывать существенное влияние на то, насколько большой может быть куча Java.