Максимальный объем памяти Java в Windows XP

103

Мне всегда удавалось выделить 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 может распознать.

Стив Куо
источник
Вы заметите разницу в максимуме между запуском приложения в 32-битной или 64-битной оболочке, по крайней мере, по моему опыту, хотя 64-битные системы WindowsXP встречаются редко.
djangofan

Ответы:

124

Имейте в виду, что в Windows есть управление виртуальной памятью, а JVM требуется только память, непрерывная в ее адресном пространстве . Таким образом, другие программы, работающие в системе, не обязательно должны влиять на размер вашей кучи. Вам будут мешать библиотеки DLL, которые загружаются в ваше адресное пространство. К сожалению, оптимизации в Windows, которые минимизируют перемещение DLL во время компоновки, повышают вероятность того, что у вас будет фрагментированное адресное пространство. В число вещей, которые могут попасть в ваше адресное пространство, помимо обычных вещей, входят программное обеспечение безопасности, программное обеспечение CBT, шпионское ПО и другие формы вредоносного ПО. Вероятными причинами расхождений являются различные исправления безопасности, версии среды выполнения C и т. Д. Драйверы устройств и другие биты ядра имеют свое собственное адресное пространство (другие 2 ГБ из 4 ГБ 32-разрядного пространства).

Вы можете попробовать выполнить привязку DLL в процессе JVM и попытаться перебазировать вашу DLL в более компактное адресное пространство. Не весело, но если ты в отчаянии ...

В качестве альтернативы вы можете просто переключиться на 64-битную Windows и 64-битную JVM. Несмотря на то, что предлагали другие, хотя он потребляет больше оперативной памяти, у вас будет гораздо больше непрерывного виртуального адресного пространства, и выделение 2 ГБ непрерывно будет тривиальным.

Кристофер Смит
источник
5
Используйте Process Explorer, чтобы увидеть, где в памяти загружаются библиотеки DLL. Часто обновленный драйвер застревает в середине вашего адресного пространства. Используя команду REBASE, вы можете легко избавиться от них. Однако имейте в виду, что dll может снова обновиться и сломаться.
brianegge, 06
2
Я никогда не принимал это как ответ, но stackoverflow пометил его как ответ.
Стив Куо,
@Christopher, можно ли использовать 64-битную JVM на 32-битной Windows XP?
Pacerier
@Pacerier Извините, я пропустил ваш запрос. AFAIK, это невозможно. В OS X были некоторые уловки для 64-битного пользовательского пространства с 32-битным ядром, но я не слышал о таких вещах для Windows.
Кристофер Смит
@ChristopherSmith, Кстати, вы упомянули, что « другие программы, работающие в системе, не обязательно должны влиять на размер вашей кучи ». Если да, то как объяснить этот результат: stackoverflow.com/questions/9303889/… ?
Pacerier
50

Это связано с непрерывной памятью.

Вот некоторая информация, которую я нашел в Интернете для тех, кто спрашивал об этом раньше, предположительно от "бога виртуальных машин":

Причина, по которой нам нужна непрерывная область памяти для кучи, заключается в том, что у нас есть набор сторонних структур данных, которые индексируются (масштабированными) смещениями от начала кучи. Например, мы отслеживаем обновления ссылок на объекты с помощью «массива меток карточек», который имеет один байт на каждые 512 байтов кучи. Когда мы сохраняем ссылку в куче, мы должны отметить соответствующий байт в массиве меток карты. Мы сдвигаем вправо адрес назначения магазина и используем его для индексации массива карточек. Веселая адресация арифметических игр, которые вы не можете сделать на Java, в которые вы можете (придется :-) играть на C ++.

Обычно у нас нет проблем с получением скромных смежных регионов (примерно до 1,5 ГБ на Windohs, до примерно 3,8 ГБ на Solaris. YMMV.). На Windohs проблема в основном заключается в том, что некоторые библиотеки загружаются до запуска JVM, что разбивает адресное пространство. Использование переключателя / 3GB не приведет к перебазированию этих библиотек, поэтому они по-прежнему являются для нас проблемой.

Мы знаем, как создавать кучи фрагментов, но их использование связано с некоторыми накладными расходами. У нас больше запросов на более быстрое управление хранилищем, чем на большие кучи в 32-битной JVM. Если вам действительно нужны большие кучи, переключитесь на 64-битную JVM. Нам по-прежнему нужна непрерывная память, но ее гораздо проще получить в 64-битном адресном пространстве.

Ури
источник
Это очень интересно. Я всегда спрашивал себя, зачем 1500 МБ, теперь получил, спасибо!
Тим Бют
3
Извините за ответ на давний вопрос, но это лучший ответ, который я когда-либо видел. Но почему JVM дает сбой при запуске, если не может получить максимальный размер кучи? Разве ему не следует спокойно соглашаться на лучший размер сверх минимума ?
Stroboskop
19

Ограничения на размер кучи Java для Windows:

  • максимально возможный размер кучи на 32-битной Java: 1,8 ГБ
  • рекомендуемый предел размера кучи для 32-разрядной версии Java: 1,5 ГБ (или 1,8 ГБ с опцией / 3 ГБ)

Это не поможет вам увеличить кучу Java, но теперь вы знаете, что не можете выйти за рамки этих значений.

MicSim
источник
10

Oracle JRockit , который может обрабатывать несмежную кучу, может иметь размер кучи Java 2,85 ГБ в Windows 2003 / XP с переключателем / 3GB. Кажется, что фрагментация может сильно повлиять на размер кучи Java.

Кире Хэглин
источник
6

JVM требуется непрерывная память, и в зависимости от того, что еще работает, что выполнялось раньше и как Windows управляла памятью, вы можете получить до 1,4 ГБ непрерывной памяти. Я думаю, что 64-битная Windows допускает большие кучи.

Джеймс А. Н. Штауфер
источник
2
Я думаю, что современная операционная система эмулирует непрерывную память для. Начиная с 80486, архитектура x86 поддерживает разбиение по страницам, чтобы упростить перестановку физической памяти.
Mnementh 01
3
Мнемет: Во-первых, в WINAPI есть специальный API (AllocateUserPhysicalPages) для расширенных инструментов, таких как базы данных и виртуальные машины, которым лучше управлять своей памятью с помощью Windows. Во-вторых, пейджинг - это функция защищенного режима 80386, а не 80486.
Тамаш Чинеге,
6

JVM Sun требует непрерывную память. Таким образом, максимальный объем доступной памяти определяется фрагментацией памяти. В частности, DLL-файлы драйверов имеют тенденцию фрагментировать память при загрузке по некоторому предопределенному базовому адресу. Итак, ваше оборудование и его драйверы определяют, сколько памяти вы можете получить.

Два источника для этого с заявлениями инженеров Sun: форум блог

Может еще одна JVM? Вы пробовали Harmony ? Думаю, они планировали разрешить прерывистую память.

утка
источник
Но мне удалось выделить 1300 МБ на машине всего с 1 ГБ ОЗУ (плюс виртуальная память). Моя машина с 2 ГБ ОЗУ (также с виртуальной памятью) может выделить только 1200 МБ.
Стив Куо,
Гармония мертва, не так ли?
Pacerier
Ага: «Apache Harmony покидает Apache Software Foundation с 16 ноября 2011 года».
bobbel
3

Я думаю, что это больше связано с тем, как настроена Windows, как намекает этот ответ: Java -Xmx Option

Еще несколько тестов: мне удалось выделить 1300 МБ на старой машине с Windows XP, имея всего 768 МБ физической памяти (плюс виртуальная память). На моем компьютере с 2 ГБ оперативной памяти я могу получить только 1220 МБ. На различных других корпоративных машинах (со старой Windows XP) мне удалось получить 1400 МБ. Машина с ограничением в 1220 МБ довольно новая (только что купленная у Dell), поэтому, возможно, она имеет более новые (и более раздутые) Windows и библиотеки DLL (она работает под управлением Window XP Pro версии 2002 SP2).

Стив Куо
источник
На это также могут повлиять ваши настройки виртуальной памяти.
skaffman,
Все машины, на которых я тестировал, имеют виртуальную память как минимум в два раза больше, чем физическая RAM.
Стив Куо,
обратите внимание, что вы действительно никогда не хотите действительно использовать виртуальную память с java, потому что производительность GC станет очень плохой. Объем памяти зависит от того, какие библиотеки DLL уже были загружены и фрагментировали память.
kohlerm
2

Я получил это сообщение об ошибке при запуске java-программы с виртуального VPS (с ограниченным объемом памяти). Я не указывал никаких аргументов памяти и обнаружил, что мне нужно явно установить небольшую величину, поскольку значение по умолчанию должно быть слишком большим. Например, -Xmx32m (очевидно, необходимо настроить в зависимости от запускаемой программы).

Просто поместите это здесь на случай, если кто-то еще получит указанное выше сообщение об ошибке, не указав большой объем памяти, как это сделал вопрошатель.

Уильям Деннисс
источник
1

Sun JDK / JRE требует непрерывного объема памяти, если вы выделяете огромный блок.

ОС и начальные приложения имеют тенденцию выделять фрагменты во время загрузки, которые фрагментируют доступную оперативную память. Если непрерывный блок НЕ доступен, SUN JDK не может его использовать. JRockit от Bea (приобретенный Oracle) может распределять память по частям.

Анжанб
источник
1

Кажется, что все говорят о непрерывной памяти, но забыли признать более насущную проблему.

Даже при 100% непрерывном распределении памяти у вас не может быть размера кучи 2 ГиБ в 32-разрядной ОС Windows (* по умолчанию). Это связано с тем, что 32-разрядные процессы Windows не могут обрабатывать более 2 ГиБ пространства.

Процесс Java будет содержать perm gen (до Java 8), размер стека на поток, накладные расходы JVM / библиотеки (которые в значительной степени увеличиваются с каждой сборкой) в дополнение к куче .

Кроме того, флаги JVM и их значения по умолчанию меняются от версии к версии. Просто запустите следующее, и вы получите некоторое представление:

 java -XX:+PrintFlagsFinal

Многие параметры влияют на разделение памяти в куче и из нее. Оставляя вам более или менее 2 ГиБ для игры ...

Чтобы повторно использовать части этого моего ответа (о Tomcat, но применимо к любому процессу Java):

ОС Windows ограничивает выделение памяти 32-разрядным процессам всего 2 ГиБ (по умолчанию).

[Вы сможете] выделить около 1,5 ГиБ кучи, потому что процессу выделяется и другая память (служебные данные JVM / библиотеки, пространство для перманентного поколения и т. Д.).

Почему 32-разрядная версия Windows ограничивает адресное пространство процесса 2 ГБ, а 64-разрядная Windows - 4 ГБ?

Другие современные операционные системы [cough Linux] позволяют 32-битным процессам использовать все (или большую часть) адресного пространства 4 ГиБ.

Тем не менее, 64-битные ОС Windows могут быть настроены для увеличения лимита 32-битных процессов до 4 ГиБ (3 ГиБ для 32-битных):

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366778(v=vs.85).aspx

Майкл
источник
1
Этот ответ касается только того, почему он может выделить только 2 ГБ, а не почему он может выделить 1,4 ГБ на одном компьютере и только 1,2 ГБ на другом. Он не достигает ваших пределов 1,5 ГБ, 2 ГБ или 4 ГБ, указанных здесь.
vapcguy 09
1
Параграф о флагах JVM в некоторой степени объясняет, почему память может различаться между версиями. Кроме того, обратите внимание на мою точку зрения о том, что параметр кучи всегда составляет (большую) долю от общего размера процесса - поэтому параметр ниже может по-прежнему достигать предела процесса в 2 ГиБ - другой может быть ограничен непрерывным распределением памяти.
Michael
Или, возможно, ограничение в 1,5 ГБ на выделение 1,4 ГБ, которое он делает. Теперь это имеет больше смысла - спасибо за это разъяснение.
vapcguy
0

Вот как увеличить размер подкачки

  1. щелкните правой кнопкой мыши на моем компьютере ---> свойства ---> Дополнительно
  2. в разделе производительности нажмите настройки
  3. щелкните вкладку Advanced
  4. в разделе «Виртуальная память» нажмите «Изменить». Он покажет текущий размер страницы.
  5. Выберите Диск, на котором доступно место на жестком диске.
  6. Укажите начальный и максимальный размер ... например, начальный размер 0 МБ и максимальный размер 4000 МБ. (Столько, сколько вам потребуется)
Израиль Маргулис
источник
0

** Существует множество способов изменить размер кучи, например,

  1. файл-> настройка-> сборка, исключение, развертывание-> компилятор здесь вы найдете размер кучи
  2. файл-> настройка-> сборка, исключение, развертывание-> компилятор-> andriod здесь также вы найдете размер кучи. Вы можете сослаться на это для проекта andriod, если столкнетесь с той же проблемой.

Для меня сработало

  1. Установите правильный путь JAVA_HOME, если вы обновили java.

  2. создать новую системную переменную компьютер-> свойства-> расширенные настройки- > создать новую системную переменную

имя: _JAVA_OPTION значение: -Xmx750m

К вашему сведению: вы можете найти вариант VM по умолчанию в Intellij help- > edit custom VM option , В этом файле вы видите минимальный и максимальный размер кучи. **

Аканкша гор
источник
-1

Во-первых, бесполезно использовать файл подкачки, когда у вас 4 ГБ ОЗУ. Windows не может получить доступ к более чем 4 ГБ (на самом деле, меньше из-за дыр в памяти), поэтому файл подкачки не используется.

Во-вторых, адресное пространство делится на две части: половина для ядра, половина для пользовательского режима. Если вам нужно больше ОЗУ для ваших приложений, используйте параметр / 3GB в boot.ini (убедитесь, что java.exe помечен как «большой адрес» (дополнительную информацию можно найти в Google).

В-третьих, я думаю, вы не можете выделить полные 2 ГБ адресного пространства, потому что java тратит некоторую внутреннюю память (для потоков, JIT-компилятора, инициализации виртуальной машины и т. Д.). Для получения дополнительных сведений используйте переключатель / 3GB.

user17544
источник
1
Идея о бесполезности файла подкачки с 4 ГБ или ОЗУ неверна. Без файла подкачки операционная система не может вытеснить неиспользуемые данные процесса (пространство стека для неиспользуемых служб и т. Д.) Из физической ОЗУ, тем самым уменьшая объем ОЗУ, доступный для реальной работы. Наличие файла подкачки освобождает оперативную память.
никто