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

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


person Steve Kuo    schedule 05.10.2008    source источник
comment
Вы заметите разницу в максимуме между запуском приложения в 32-битной или 64-битной оболочке, по крайней мере, по моему опыту, хотя 64-битные системы WindowsXP встречаются редко.   -  person djangofan    schedule 12.01.2013
comment
wiki.eclipse.org/Eclipse.ini - oracle.com/technetwork/java/javase/.   -  person Andrew    schedule 11.05.2018


Ответы (13)


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

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

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

person Christopher Smith    schedule 31.01.2009
comment
Используйте Process Explorer, чтобы увидеть, где в памяти загружаются библиотеки DLL. Часто обновленный драйвер застревает в середине вашего адресного пространства. Используя команду REBASE, вы можете легко избавиться от них. Однако имейте в виду, что dll может снова обновиться и сломаться. - person brianegge; 06.02.2009
comment
@Christopher, можно ли использовать 64-битную JVM на 32-битной Windows XP? - person Pacerier; 10.05.2014
comment
@Pacerier Извините, я пропустил ваш запрос. AFAIK, это невозможно. В OS X были некоторые уловки для 64-битного пользовательского пространства с 32-битным ядром, но я не слышал о таких вещах для Windows. - person Christopher Smith; 20.04.2015
comment
@ChristopherSmith, кстати, вы упомянули, что другие программы, работающие в системе, не обязательно должны влиять на размер вашей кучи. Если да, то как объяснить этот результат: stackoverflow.com/questions/9303889/? - person Pacerier; 21.01.2016
comment
@brianegge Как использовать обозреватель процессов для просмотра загруженных dll? - person speedplane; 24.06.2016
comment
Может ли подобная проблема возникнуть из-за использования разделяемых библиотек в системе Unix? - person Nikita Tkachenko; 12.04.2020

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

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

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

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

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

person Uri    schedule 31.01.2009
comment
Это очень интересно. Я всегда спрашивал себя, зачем 1500 МБ, теперь получил, спасибо! - person Tim Büthe; 02.10.2012
comment
Извините за ответ на давний вопрос, но это лучший ответ, который я когда-либо видел. Но почему JVM дает сбой при запуске, если она не может получить максимальный размер кучи? Разве ему не следует спокойно соглашаться на лучший размер выше минимального? - person Stroboskop; 29.07.2014

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

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

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

person MicSim    schedule 31.01.2009

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

person Kire Haglin    schedule 01.02.2009

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

person James A. N. Stauffer    schedule 05.10.2008
comment
Я думаю, что современная операционная система эмулирует непрерывную память для. Начиная с 80486, архитектура x86 поддерживает разбиение на страницы, чтобы упростить перестановку физической памяти. - person Mnementh; 01.02.2009
comment
Мнемет: Во-первых, в WINAPI есть специальный API (AllocateUserPhysicalPages) для расширенных инструментов, таких как базы данных и виртуальные машины, которым лучше управлять своей памятью с помощью Windows. Во-вторых, подкачка - это функция защищенного режима 80386, а не 80486. - person Tamas Czinege; 03.02.2009

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

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

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

person the.duckman    schedule 06.10.2008
comment
Но мне удалось выделить 1300 МБ на машине всего с 1 ГБ ОЗУ (плюс виртуальная память). Моя машина с 2 ГБ ОЗУ (также с виртуальной памятью) может выделить только 1200 МБ. - person Steve Kuo; 09.10.2008
comment
Гармония мертва, не так ли? - person Pacerier; 10.05.2014
comment
Ага: Apache Harmony покидает Apache Software Foundation с 16 ноября 2011 года. - person bobbel; 10.09.2014

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

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

person Steve Kuo    schedule 05.10.2008
comment
На это также могут повлиять ваши настройки виртуальной памяти. - person skaffman; 06.10.2008
comment
Все машины, на которых я тестировал, имеют виртуальную память как минимум в два раза больше, чем физическая ОЗУ. - person Steve Kuo; 11.10.2008
comment
обратите внимание, что вы действительно никогда не хотите действительно использовать виртуальную память с java, потому что производительность GC станет очень плохой. Объем памяти зависит от того, какие библиотеки DLL уже были загружены и фрагментировали память. - person kohlerm; 19.10.2008

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

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

person William Denniss    schedule 07.04.2011

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

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

person anjanb    schedule 05.10.2008

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

Даже при 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

person Michael    schedule 12.06.2015
comment
Этот ответ касается только того, почему он может выделить только 2 ГБ, а не почему он может выделить 1,4 ГБ на одном компьютере и только 1,2 ГБ на другом. Он не достигает ваших пределов 1,5 ГБ, 2 ГБ или 4 ГБ, указанных здесь. - person vapcguy; 09.06.2017
comment
Параграф о флагах JVM в некоторой степени объясняет, почему память может различаться между версиями. Также обратите внимание на мою точку зрения о том, что параметр кучи всегда составляет (большую) долю от общего размера процесса - поэтому параметр ниже может по-прежнему достигать предела process в 2 ГиБ - другой может быть ограничен смежными выделение памяти. - person Michael; 12.06.2017
comment
Или, возможно, ограничение в 1,5 ГБ на выделение 1,4 ГБ, которое он делает. Теперь это имеет больше смысла - спасибо за это разъяснение. - person vapcguy; 13.06.2017

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

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

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

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

Что сработало для меня, было

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

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

name: _JAVA_OPTION value: -Xmx750m

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

person Akanksha gore    schedule 17.02.2020

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

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

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

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