Як поділяється пул пам'яті 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) та запитання щодо збирання сміття (JDK 1.4)
kdgregory

Відповіді:


327

Купа пам'яті

Пам'ять купи - це область даних часу виконання, з якої Java VM виділяє пам'ять для всіх екземплярів і масивів класу. Купа може мати фіксований або змінний розмір. Збір сміття - це система автоматичного управління пам’яттю, яка відновлює купу пам’яті для об’єктів.

  • Eden Space : Пул, з якого спочатку виділяється пам'ять для більшості об'єктів.

  • Космос для виживання : Басейн, що містить предмети, які пережили збирання сміття з простору Едему.

  • Тинуровані покоління або старий ген : басейн, що містить об’єкти, які існували певний час у просторі вцілілих.

Пам'ять, що не купується

Пам'ять, що не має купи, включає в себе область методів, що поділяється між усіма потоками та пам'ять, необхідну для внутрішньої обробки або оптимізації для Java VM. Він зберігає структури за класом, такі як постійний пул виконання, дані про поле та методи, а також код методів та конструкторів. Область методу логічно є частиною купи, але, залежно від реалізації, Java VM може не збирати сміття або ущільнювати його. Як і в пам'яті купи, область методу може мати фіксований або змінний розмір. Пам'ять для області методу не повинна бути суміжною.

  • Постійне покоління : Пул, що містить усі відображаючі дані самої віртуальної машини, такі як об'єкти класу та методу. Що стосується Java VM, які використовують обмін даними класу, це покоління поділяється на області лише для читання та для читання та запису.

  • Кеш коду : HotSpot Java VM також включає кеш коду, що містить пам'ять, яка використовується для компіляції та зберігання нативного коду.

Ось деяка документація щодо використання Jconsole .


4
Я не впевнений, що @dfa цілком коректний, оскільки в специфікації Java Virtual Machine чітко зазначено: "Хоча область методу логічно є частиною купи, прості реалізації можуть вирішити не збирати сміття чи ущільнювати його". Однак зрозуміло, що jconsole показує кеш-код коду та постійне покоління як non-Heap, що, здається, суперечить специфікації. Чи може хтось надати більше роз’яснень щодо цього протиріччя?
Джеймс Блум

@JamesBloom - мені було цікаво те саме. Навіть незважаючи на те, що основне визначення визначає, до якого типу належить пул пам’яті (heap / non-heap), він може змінити стан явно?
Umang Desai

2
Документ, на який він отримав прізвисько: docs.intergral.com/pages/viewpage.action?pageId=22478944 Документ містить ще одну хорошу інформацію про JVM, яку варто переглянути,
Стів Сіберт

1
Незважаючи на багато відгуків, насправді це не така змістовна відповідь. Наприклад, що означають "об’єкти, що пережили збирання сміття з Едемського простору"? Чи переміщуються ці об’єкти до простору виживаючих з Едему після виживання, або їхній простір в Едені вважається простором Survivor? А як щодо збору сміття в басейнах, крім простору Еден, це трапляється? Зовсім не зрозуміло.
Михайло Батцер

і не забудьте стек (на стороні без купи) :)
Беззубий провидець

70

Нове ключове слово виділяє пам'ять на купі Java. Купа - це основний пул пам'яті, доступний для всієї програми. Якщо не вистачає пам'яті для виділення цього об’єкта, JVM намагається повернути деяку пам’ять з купи за допомогою сміття. Якщо він все ще не може отримати достатню кількість пам'яті, викидається OutOfMemoryError, і JVM виходить.

Купа розбита на кілька різних розділів, званих поколіннями. Оскільки об’єкти виживають більше сміттєзбірників, їх рекламують у різні покоління. Старші покоління сміття збирають не так часто. Оскільки ці об’єкти вже зарекомендували себе довше живуть, вони рідше збирають сміття.

Коли споруди спочатку побудовані, вони розподіляються в просторі Едему. Якщо вони пережиють збір сміття, їх переводять у космос Survivor, і якщо вони там проживуть досить довго, їх відводять до покоління, яке перебуває у штаті. Це покоління сміття збирають набагато рідше.

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

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


Діаграма виглядає дуже пояснювальною ... Чи справедливо це для будь-якого алгоритму GC. G1 мають різний набір.
Venkateswara Rao

@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 Heap - це частина пам'яті, виділеної JVM операційною системою.

Об'єкти мешкають у районі, що називається купами. Купа створюється при запуску JVM і може збільшуватись або зменшуватися в розмірі під час роботи програми. Коли купа стає повноцінною, збирається сміття.

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

Ви можете знайти більш детальну інформацію про космос Eden, Space Survivor, Tenured Space та Stal Generation у нижченаведеному питанні SE.

Покоління молодих, тинурованих та пермських

PermGen був замінений на Metaspace з моменту випуску Java 8.

Щодо ваших запитів:

  1. Eden Space, Space Survivor, Tenured Space - частина пам'яті купи
  2. Метапростір і кеш коду є частиною негромової пам'яті.

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.