Максимальная память 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 может распознать.
12 ответов
Имейте в виду, что Windows имеет управление виртуальной памятью, а JVM нужна только память, смежная с ее адресным пространством. Таким образом, другие программы, работающие в системе, не обязательно должны влиять на размер кучи. На вашем пути будут библиотеки DLL, загружаемые в ваше адресное пространство. К сожалению, оптимизации в Windows, которые сводят к минимуму перемещение библиотек DLL во время компоновки, повышают вероятность фрагментарного адресного пространства. Вещи, которые могут врезаться в ваше адресное пространство помимо обычных вещей, включают в себя программное обеспечение безопасности, программное обеспечение CBT, шпионское ПО и другие виды вредоносных программ. Вероятными причинами отклонений являются различные исправления безопасности, версии среды выполнения C и т. Д. Драйверы устройств и другие биты ядра имеют свое собственное адресное пространство (остальные 2 ГБ 32-разрядного пространства 4 ГБ).
Вы можете попробовать выполнить привязки к 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-битное адресное пространство.
Ограничения размера кучи Java для Windows:
- максимально возможный размер кучи на 32-битной Java: 1,8 ГБ
- рекомендуемый предел размера кучи на 32-битной Java: 1,5 ГБ (или 1,8 ГБ с параметром /3 ГБ)
Это не поможет вам получить большую кучу Java, но теперь вы знаете, что не можете выйти за пределы этих значений.
Oracle JRockit, который может обрабатывать несмежные кучи, может иметь размер кучи Java 2,85 ГБ в Windows 2003/XP с параметром /3GB. Кажется, что фрагментация может сильно повлиять на размер кучи Java.
JVM требуется непрерывная память, и в зависимости от того, что еще работает, что работало раньше и как windows управляла памятью, вы можете получить до 1,4 ГБ непрерывной памяти. Я думаю, что 64-битная Windows позволит большие кучи.
JVM от Sun нуждается в непрерывной памяти. Таким образом, максимальный объем доступной памяти определяется фрагментацией памяти. В частности, DLL-файлы драйвера имеют тенденцию фрагментировать память при загрузке в какой-либо заранее заданный базовый адрес. Таким образом, ваше оборудование и его драйверы определяют, сколько памяти вы можете получить.
Два источника для этого с заявлениями инженеров Sun: форум блог
Может быть, еще одна JVM? Ты пробовал Гармонию? Я думаю, что они планировали разрешить не непрерывную память.
Я думаю, что это больше связано с тем, как Windows настроена, как намекает этот ответ: Java -Xmx Option
Еще несколько тестов: я смог выделить 1300 МБ на старой машине с Windows XP и только 768 МБ физической памяти (плюс виртуальная память). На моей машине с 2 ГБ ОЗУ я могу получить только 1220 МБ. На других корпоративных машинах (с более старой Windows XP) мне удалось получить 1400 МБ. Машина с ограничением в 1220 МБ является довольно новой (только что купленной у Dell), поэтому, возможно, она имеет более новые (и более раздутые) Windows и библиотеки DLL (работает под управлением Windows XP Pro Version 2002 SP2).
Я получил это сообщение об ошибке при запуске Java-программы из VPS-сервера Virtuozzo (с ограниченной памятью). Я не указал никаких аргументов памяти и обнаружил, что должен был явно установить небольшое количество, поскольку значение по умолчанию должно быть слишком высоким. Например, -Xmx32m (очевидно, необходимо настроить в зависимости от программы, которую вы запускаете).
Просто поместите это здесь на случай, если кто-то еще получит вышеуказанное сообщение об ошибке, не указывая большой объем памяти, как это сделал спрашивающий.
JDK/JRE от Sun требует непрерывного объема памяти, если вы выделяете огромный блок.
ОС и исходные приложения имеют тенденцию выделять фрагменты во время загрузки, которые фрагментируют доступную оперативную память. Если непрерывный блок НЕ доступен, SUN JDK не может его использовать. JRockit от Bea(приобретенный Oracle) может распределять память по частям.
Кажется, что все отвечают о смежной памяти, но забыли признать более насущную проблему.
Даже при 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 / библиотеки, пространство perm gen и т. Д.).
Другие современные операционные системы [cough Linux] позволяют 32-битным процессам использовать все (или большинство) из адресуемого пространства 4 ГиБ.
Тем не менее, 64-разрядные ОС Windows могут быть настроены для увеличения предела 32-разрядных процессов до 4 ГиБ (3 ГБ на 32-разрядных):
http://msdn.microsoft.com/en-us/library/windows/desktop/aa366778(v=vs.85).aspx
Вот как увеличить размер подкачки
- щелкните правой кнопкой мыши на моем компьютере ---> Свойства ---> Дополнительно
- в разделе производительности нажмите настройки
- нажмите вкладку Дополнительно
- в разделе Виртуальная память нажмите изменить. Это покажет ваш текущий размер подкачки.
- Выберите диск, на котором доступно место на жестком диске.
- Укажите начальный размер и максимальный размер... например, начальный размер 0 МБ и максимальный размер 4000 МБ. (Столько, сколько вам потребуется)
** Существует множество способов изменить размер кучи, например,
- файл-> настройка-> сборка, исключение, развертывание-> компилятор здесь вы найдете размер кучи
- файл-> настройка-> сборка, исключение, развертывание-> компилятор-> andriod здесь также вы найдете размер кучи. Вы можете сослаться на это для проекта andriod, если столкнетесь с той же проблемой.
Что сработало для меня, было
Установите правильный путь JAVA_HOME, если вы обновили java.
создать новую системную переменную компьютер-> свойства-> расширенные настройки-> создать новую системную переменную
имя: _JAVA_OPTION значение: -Xmx750m
К вашему сведению: вы можете найти опцию VM по умолчанию в Intellijhelp-> edit custom VM option, В этом файле вы видите минимальный и максимальный размер кучи.**
Во-первых, использование файла подкачки при наличии 4 ГБ ОЗУ бесполезно. Windows не может получить доступ к более чем 4 ГБ (фактически, меньше из-за дыр в памяти), поэтому файл подкачки не используется.
Во-вторых, адресное пространство делится на 2, половина для ядра, половина для режима пользователя. Если вам требуется больше оперативной памяти для ваших приложений, используйте параметр /3GB в файле boot.ini (убедитесь, что java.exe помечен как "поддерживающий большой адрес" (Google для получения дополнительной информации).
В-третьих, я думаю, что вы не можете выделить все 2 ГБ адресного пространства, поскольку Java тратит часть внутренней памяти (на потоки, JIT-компилятор, инициализацию виртуальной машины и т. Д.). Используйте параметр /3GB для большего.