В частности, в Windows причина заключается в сочетании реализации точки доступа (JVM Sun / Oracle) и DLL Windows.
32-битный код имеет доступ к виртуальному адресному пространству 4 ГБ (есть расширения, которые позволяют больше, но я не буду вдаваться в них).
в 32-битных окнах верхние 2 ГБ этого виртуального адресного пространства зарезервированы для использования операционной системы (некоторые версии ОС принимают / 3GB в качестве параметра загрузки, позволяющего выделить 3 ГБ доступного для пользователя пространства).
Кроме того, любые используемые вами библиотеки (* .dll) отображаются на части этого адресного пространства. по умолчанию файлы * .dll базы Windows загружаются на отметке ~ 1,6 ГБ (немного отличается в зависимости от версии ОС и уровня исправления)
Вдобавок ко всему этому JVM хот-спота поддерживает выделение только одного непрерывного фрагмента памяти для использования в качестве пространства кучи.
Итак, если вы попытаетесь представить это в своей голове, вы увидите, что у вас есть свободная область размером ~ 2 ГБ с "стеной" из файлов windows * .dll, загруженных на ~ 1,6 ГБ. это логика, стоящая за этой цифрой. это также означает, что даже если вы укажете флаг / 3GB, Sun / oracle JVM не сможет его использовать. некоторые другие виртуальные машины лучше справляются с фрагментированной кучей - например, jrockit VM
вы также можете попробовать перебазировать DLL-файлы Windows, чтобы они загружались в более высокие адреса памяти и сжимали еще немного полезного места в куче, но процесс хрупкий.
также обратите внимание, что вполне возможно, что драйверы / приложения, загруженные на определенных машинах (например, антивирусное программное обеспечение), будут внедрять свои собственные * .dll в процесс java, и эти dll могут быть загружены по еще более низким адресам памяти, что еще больше уменьшит вашу используемую кучу космос.
в 64-битных версиях Windows адресный лимит составляет 8–128 ТБ, а физический лимит сейчас составляет 64 ТБ
person
radai
schedule
07.02.2014