Подтвердить что ты не робот

Понимание распределения памяти JVM и Java из памяти: пустое пространство

Я вникаю в понимание того, как распределение памяти работает в JVM. Я пишу приложение, в котором я получаю исключение из памяти: исключения в Heap Space.

Я понимаю, что могу передавать аргументы VM, такие как Xms и Xmx, для того, чтобы увеличить кучу пространства, которое JVM выделяет для текущего процесса. Это одно из возможных решений проблемы, или я могу проверить свой код на утечку памяти и исправить там проблему.

Мои вопросы:

1) Как JVM фактически распределяет память для себя? Как это связано с тем, как ОС связывает доступную память с JVM? Или, в общем, как распределяется память для любого процесса?

2) Как виртуальная память вступает в игру? Скажем, у вас есть система с 32 ГБ физической памяти, и вы выделяете все 32 ГБ для вашего Java-процесса. Скажем, что ваш процесс фактически потребляет все 32 ГБ памяти, как мы можем заставить процесс использовать виртуальную память вместо использования в исключениях OOM?

Спасибо.

4b9b3361

Ответ 1

Как JVM фактически выделяет память для себя?

Для кучи он выделяет одну большую conitnous область памяти максимального размера. Первоначально это виртуальная память, однако со временем она становится реальной памятью для частей, которые используются под управлением ОС

Как это связано с тем, как ОС связывает доступную память с JVM?

JVM не имеет понятия о свободной памяти в ОС.

Или, в общем, как распределяется память для любого процесса?

В общем случае он использует malloc и бесплатно.

Как виртуальная память вступает в игру?

Изначально выделяется виртуальная память, которая используется в реальной памяти. Это нормально для любого процесса.

Скажем, у вас есть система с 32 ГБ физической памяти, и вы выделяете все 32 ГБ для своего Java-процесса.

Вы не можете. ОС требуется некоторая память, и в других случаях будет память. Даже в JVM куча - это только часть используемой памяти. Если у вас есть 32 ГБ памяти, я предлагаю максимум в 20 ГБ.

Скажем, что ваш процесс фактически потребляет все 32 ГБ памяти,

Скажем, у вас есть 48 ГБ, и вы запускаете процесс, который использует 32 ГБ основной памяти.

как мы можем заставить процесс использовать виртуальную память вместо использования в исключениях OOM?

Приложение использует виртуальную память с самого начала. Вы не можете сделать кучу слишком большой, потому что, если она начнет замену вашей машины (а не только вашего приложения), она станет непригодной.

Вы можете использовать больше памяти, чем физическую, с осторожностью используя память кучи. Однако управляемая память должна находиться в физической памяти, поэтому, если вам нужна куча 32 ГБ, купите 64 ГБ основной памяти.

Ответ 2

JVM (или, в любом случае, любой процесс), который хочет выделить память, вызывается функцией C malloc. Эта функция поддерживает память кучи времени выполнения C. Он, в свою очередь, получает память из ядра операционной системы - функция, используемая для этого, зависит от платформы; в Linux он может использовать системные вызовы brk или sbrk.

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

Виртуальная память полностью обрабатывается ядром операционной системы. Ядро управляет отображением страниц физической памяти в адресное пространство различных процессов; если есть меньше физической памяти, чем требуется всем процессам в системе, то ядро ​​ОС поменяет часть на диск.

Вы не можете (и не должны) принудительно использовать процессы для использования виртуальной памяти. Он прозрачен для вашего процесса.

Если вы получаете ошибки "из памяти", то причиной могут быть:

  • Превышены пределы JVM. Они контролируются различными аргументами командной строки и/или свойствами, указанными в вашем вопросе.

  • Возможно, в ОС не было места подкачки (или не было настроено какое-либо место подкачки). Или некоторые ОС даже не поддерживают виртуальную память, и в этом случае у вас закончилась реальная память.

  • В большинстве ОС есть возможности администратора ограничить объем памяти, потребляемой процессом - например, в Linux системный вызов setrlimit и/или команда ulimit shell, обе из которых устанавливают пределы, которые будет наблюдать ядро. Если процесс запрашивает больше памяти, чем разрешено ограничениями, попытка не будет выполнена (обычно это приводит к сообщению из памяти).

Ответ 3

  • JVM выделяет кучу памяти Java из ОС, а затем управляет куча для приложения Java. Когда приложение создает новый объекта, JVM выделяет смежную область памяти кучи для храните его. Объект в куче, на который ссылается любой другой объект является "живым" и остается в куче, пока он по-прежнему остается ссылки. Объекты, на которые больше не ссылаются, являются мусором и могут быть очищены из кучи, чтобы вернуть место, которое они занимают. JVM выполняет сбор мусора (GC) для удаления этих объектов, реорганизация объектов, оставшихся в куче.
    Источник: http://pubs.vmware.com/vfabric52/index.jsp?topic=/com.vmware.vfabric.em4j.1.2/em4j/conf-heap-management.html

  • В системе, использующей виртуальную память, физическая память делится на страницы с одинаковым размером. Память, обрабатываемая процессом, также разделена на логические страницы того же размера. Когда процесс ссылается на адрес памяти, диспетчер памяти извлекает с диска страницу, которая включает ссылочный адрес и помещает его в свободную физическую страницы в ОЗУ.

Источник: http://searchstorage.techtarget.com/definition/virtual-memory