Как разделить пул памяти Java?


224

В настоящее время я наблюдаю за Java-приложением с помощью jconsole. Вкладка памяти позволяет выбирать между:

Heap Memory Usage
Non-Heap Memory Usage
Memory Pool “Eden Space”
Memory Pool “Survivor Space”
Memory Pool “Tenured Gen”
Memory Pool “Code Cache”
Memory Pool “Perm Gen”

В чем разница между ними?


Предполагая, что вы используете Sun JDK, лучший ответ будет найден в их документации: Настройка сборки мусора (JDK 1.5) и FAQ по сборке мусора (JDK 1.4)
kdgregory

Ответы:


327

Куча памяти

Куча памяти - это область данных времени выполнения, из которой Java VM выделяет память для всех экземпляров и массивов классов. Куча может быть фиксированного или переменного размера. Сборщик мусора - это система автоматического управления памятью, которая восстанавливает кучу памяти для объектов.

  • Eden Space : Пул, из которого память изначально выделена для большинства объектов.

  • Пространство оставшихся в живых : Пул, содержащий объекты, которые пережили сборку мусора пространства Эдема.

  • Tenured Generation или Old Gen : пул, содержащий объекты, которые существовали в пространстве выживших в течение некоторого времени.

Не куча памяти

Память без кучи включает в себя область методов, совместно используемую всеми потоками, и память, необходимую для внутренней обработки или оптимизации для Java VM. Он хранит структуры для каждого класса, такие как пул констант времени выполнения, данные полей и методов, а также код для методов и конструкторов. Область метода является логически частью кучи, но, в зависимости от реализации, виртуальная машина Java может не собирать и не собирать мусор. Как и в куче памяти, область метода может иметь фиксированный или переменный размер. Память для области метода не должна быть смежной.

  • Постоянная генерация : пул, содержащий все отражающие данные самой виртуальной машины, такие как объекты класса и метода. В случае виртуальных машин Java, которые используют общий доступ к данным классов, это поколение делится на области только для чтения и чтения и записи.

  • Кэш кода : Java VM HotSpot также содержит кэш кода, содержащий память, которая используется для компиляции и хранения собственного кода.

Вот некоторая документация о том, как использовать Jconsole .


4
Я не уверен, что @dfa полностью корректен, поскольку в Спецификации виртуальной машины Java четко сказано: «Хотя область метода является логически частью кучи, простые реализации могут не собирать и не собирать мусор». Однако ясно, что jconsole отображает кэш кода и постоянную генерацию как не-кучу, что противоречит спецификации. Кто-нибудь может дать больше разъяснений по этому противоречию?
Джеймс Блум,

@JamesBloom - мне было интересно то же самое. Несмотря на то, что в базовом определении указано, к какому типу относится пул памяти (heap / non-heap), оно может измениться - это состояние явно?
Уманг Десаи

2
документ, от которого это получилось так: docs.intergral.com/pages/viewpage.action?pageId=22478944 Документ содержит некоторые другие полезные сведения о JVM, которые стоит посмотреть
Стив Зиберт,

1
Несмотря на множество голосов, на самом деле это не очень значимый ответ. Например, что означают «объекты, которые пережили сборку мусора в Эдемском пространстве»? Перемещаются ли эти объекты в космос выживших из Эдема после выживания или их пространство в Эдеме считается пространством выживших? А как насчет сбора мусора в пулах, отличных от пространства Eden, это происходит? Совершенно не ясно.
Михаил Батцер

и не забывайте стек (на стороне без кучи) :)
Беззубый Провидец

70

Новое ключевое слово выделяет память в куче Java. Куча - это основной пул памяти, доступный для всего приложения. Если для этого объекта недостаточно памяти, JVM пытается освободить часть памяти из кучи с помощью сборки мусора. Если он все еще не может получить достаточно памяти, выдается ошибка OutOfMemoryError и JVM завершает работу.

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

Когда объекты впервые создаются, они размещаются в пространстве Эдема. Если они выживают при сборе мусора, их повышают до Космоса выживших, и, если они там живут достаточно долго, они передаются Поколенному Штату. Это поколение мусора собирается гораздо реже.

Существует также четвертое поколение, называемое постоянным поколением, или PermGen. Объекты, которые здесь находятся, не подлежат сборке мусора и обычно содержат неизменяемое состояние, необходимое для работы JVM, например определения классов и пул констант String. Обратите внимание, что пространство PermGen планируется удалить из Java 8, и оно будет заменено новым пространством под названием Metaspace, которое будет храниться в собственной памяти. ссылка: http://www.programcreek.com/2013/04/jvm-run-time-data-areas/

введите описание изображения здесь введите описание изображения здесь


Диаграмма выглядит очень понятной ... Это действительно для любого алгоритма GC. У G1 другой набор.
Венкатесвара Рао

@Pythoner Я думаю, что флаг темно-фиолетового цвета должен быть, -XX:PermSizeа не так, -XX:MaxPermSizeкак он уже определен выше.
Анураг,

35

В Java8 область, не относящаяся к куче, больше не содержит PermGen, но Metaspace, который является основным изменением в Java8, должно избавлять от ошибок нехватки памяти с помощью Java, так как размер метапространства может быть увеличен в зависимости от пространства, требуемого jvm для данных класса.


1
На самом деле, есть метапространство и пространство классов: docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/…
mrswadge

23

Память кучи Java является частью памяти, выделяемой JVM операционной системой.

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

введите описание изображения здесь

Вы можете найти более подробную информацию о Eden Space, Survivor Space, Tenured Space и Permanent Generation ниже в SE вопросе

Молодое, штатное и пермское поколение

PermGen был заменен на Metaspace с момента выпуска Java 8.

По поводу ваших запросов:

  1. Eden Space, Survivor Space, Tenured Space являются частью кучи памяти
  2. Metaspace и Code Cache являются частью не кучи памяти.

Кодовый кеш: виртуальная машина Java (JVM) генерирует собственный код и сохраняет его в области памяти, которая называется кодовым кешем. JVM генерирует собственный код по разным причинам, в том числе для динамически генерируемого цикла интерпретатора, заглушек Java Native Interface (JNI) и для методов Java, которые компилируются в собственный код компилятором JIT. JIT - безусловно самый большой пользователь кодового кэша.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.