Максимальная память Java в Windows XP - PullRequest
101 голосов
/ 05 октября 2008

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

Ответы [ 12 ]

120 голосов
/ 31 января 2009

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

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

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

50 голосов
/ 31 января 2009

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

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

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

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

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

19 голосов
/ 31 января 2009

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

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

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

10 голосов
/ 02 февраля 2009

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

6 голосов
/ 06 октября 2008

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

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

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

6 голосов
/ 05 октября 2008

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

3 голосов
/ 06 октября 2008

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

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

2 голосов
/ 07 апреля 2011

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

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

1 голос
/ 12 июня 2015

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

Даже при 100% непрерывном выделении памяти в 32-разрядной ОС Windows размер кучи не может превышать 2 ГБ (* по умолчанию). Это связано с тем, что 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 ГБ?

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

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

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

1 голос
/ 05 октября 2008

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...