metaspace java что это

Русские Блоги

Java 8 metaspace

Вечное поколение

Существует много типов JVM, таких как Oralce-Sun Hotspot, Oralce JRockit, IBM J9, Taobao JVM (Taobao хороший вид!) И так далее. Конечно, лидером боевых искусств является Hotspot, это не спор. Следует отметить, что пространство PermGen доступно только в Oracle-Sun Hotspot JRockit и J9 не имеют этой области.

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

Метаданные, используемые JVM для описания классов и методов, используемых в приложении, также сохраняются в постоянном поколении. Сколько места для генерации будет использовать JVM, зависит от того, сколько классов использует приложение. Кроме того, классы и методы в библиотеке Java SE также хранятся здесь.

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

Постоянный размер поколения

Почему удалить постоянное поколение

Так куда же делись метаданные для JVM?

Элемент пространства (Метапространство)

Пространство постоянного поколения полностью удалено, и оно заменено областью, названной metaspace. После удаления постоянного поколения очевидно, что JVM игнорирует два параметра PermSize и MaxPermSize, и вы больше не видите исключение java.lang.OutOfMemoryError: PermGen error.

HotSpot JVM в JDK 8 теперь использует локальную память для представления метаданных класса. Эта область называется метапространством.

Модель распределения памяти в метапространстве

Давайте посмотрим, как JVM выделяет пространство виртуальной памяти для метаданных

Понимать _mark и _klass указатели

Чтобы понять картинку ниже, вы должны выяснить, что это за указатели.

В JVM каждый объект имеет указатель на свой собственный класс, но этот указатель указывает только на определенный класс реализации, а не на интерфейс или абстрактный класс.

_mark: 4 байта константы

_klass: указывает на второе поле в макете памяти 4-байтового объекта указателя класса (_klass, в 32-битной JVM, смещение от позиции объекта в памяти равно 4, а 64-битное равно 8) Является ли определение класса объекта в памяти.

_mark: 8-байтовая константа

_klass: 8-байтовый указатель на класс

64-битная JVM с включенным сжатием указателей: _mark: 8-байтовая константа

_klass: 4-байтовый указатель на класс

Расположение памяти объектов Java

Сжатый указатель класса Space

Эта область существует только в том случае, если сжатие указателя класса включено на 64-разрядных платформах. Для 64-битных платформ для сжатия размера указателя _klass в объекте JVM вводится пространство указателя сжатого класса (пространство указателя сжатого класса).

Расположение памяти после сжатия указателей

Указатель на метаданные класса в объекте будет сжат до 32 бит

Пространство сжатия указателя класса будет иметь базовый адрес

Разница между мета-пространством и указателем как пространство сжатия

Пространство сжатия указателя класса содержит только метаданные класса, такие как InstanceKlass, ArrayKlass, которые вступают в силу только при включенной опции UseCompressedClassPointers. Для повышения производительности здесь также хранится таблица виртуальных методов в Java. Какие типы метаданных хранятся здесь?

Метапространство содержит другие относительно большие метаданные класса, такие как методы, байтовые коды и пулы констант.

Настройка метапространства

Тюнинг MaxMetaspaceSize

Настройка CompressedClassSpaceSize

Некоторые инструменты в метапространстве

Улучшить производительность GC

Если вы понимаете концепцию metaspace, легко обнаружить, что производительность GC была улучшена.

Метапространство в java8 суммируется следующим образом:

Состояние пермского пространства

Все это пространство памяти будет удалено.

Параметры JVM: PermSize и MaxPermSize игнорируются, и выдается предупреждение (если эти два параметра установлены при включении).

Модель распределения памяти в метапространстве

Большая часть метаданных класса размещается в локальной памяти.

«Классы», используемые для описания метаданных класса, были удалены.

Метапространственная емкость

По умолчанию метаданные класса ограничены только доступной локальной памятью (емкость зависит от объема виртуальной памяти, доступной для 32-разрядных или 64-разрядных операционных систем).

Новый параметр (MaxMetaspaceSize) используется для ограничения размера локальной памяти, выделяемой метаданным класса. Если этот параметр не указан, метаскоп будет динамически корректироваться по мере необходимости во время выполнения.

Metaspace сборка мусора

Сборка мусора для классов зомби и загрузчиков классов будет выполняться, когда использование метаданных достигнет значения, установленного параметром «MaxMetaspaceSize».

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

Влияние кучи памяти Java

Некоторые разные данные были перемещены в пространство кучи Java. После обновления до JDK8 вы увидите, что пространство кучи Java увеличилось.

Метапространственный мониторинг

Использование метапространства может быть получено из подробного журнала GC HotSpot 1.8.

Два инструмента, Jstat и JVisualVM, были обновлены при тестировании с версией b75, но вы все еще можете увидеть внешний вид старого пространства PermGen.

Сравнение PermGen и Metaspace во время выполнения

Чтобы лучше понять поведение во время выполнения пространства памяти Metaspace,

Будут протестированы следующие сценарии:

Используйте JDK1.7 для запуска программ на Java, отслеживания и исчерпания объема памяти PermGen по умолчанию, равного 85 МБ.

Используйте JDK1.8 для запуска программ на Java и отслеживания процесса динамического роста и сбора мусора в новом пространстве памяти Metaspace.

Используйте JDK1.8 для запуска Java-программы и имитации исчерпания пространства памяти Metaspace объемом 128 МБ, установленного параметром «MaxMetaspaceSize».

Сначала создан код, который имитирует PermGen OOM

Читайте также:  что делать если душно и тяжело дышать в квартире

Выше приведен простой ClassA, скомпилируйте его в байт-код класса и поместите его в D: / classes, используйте URLClassLoader для загрузки этого типа в тестовый код Вышеупомянутый класс скомпилирован в класс

Это можно увидеть на скриншоте JVisualVM выше: после загрузки более 60 000 классов PermGen исчерпан. Мы также можем наблюдать процесс истощения через вывод программы и GC.

Вывод программы (извлеченная часть)

JDK 1.8 @ 64-битный тест на динамическое изменение размера Metaspace

Java Metaspace space: не ограничено (по умолчанию)

Как вы можете видеть на скриншоте выше, JVM Metaspace динамически расширяется, а использование локальной памяти увеличено с 20 МБ до 646 МБ, чтобы удовлетворить растущий спрос на память данных классов в программе. Мы также можем наблюдать событие сборки мусора JVM, пытающимся уничтожить мертвый класс или объект загрузчика классов. Однако из-за утечки нашей программы у JVM нет другого выбора, кроме как динамически расширять пространство памяти Metaspace. Программа загружает более 100 000 классов без событий OOM.

Пространство метапространства Java: 128 МБ (-XX: MaxMetaspaceSize = 128 м)

Это можно увидеть на скриншоте JVisualVM выше: после загрузки более 20 000 классов Metaspace исчерпан, очень похоже на среду выполнения JDK1.7. Мы также можем наблюдать процесс истощения через вывод программы и GC. Еще одним интересным явлением является то, что зарезервированное использование собственной памяти более чем в два раза превышает установленный максимальный размер. Это может указывать на то, что, если возможно, вы можете точно настроить стратегию емкости метапространства, чтобы не тратить локальную память.

Следующее исключение видно из вывода программы Java.

Источник

Что такое использование MetaSpace в Java 8?

Я знаю, что они заменили PermGen на MetaSpace в Java 8. Но у меня мало вопросов:—3—>

3 ответов

является ли MetaSpace по умолчанию GC собранным?

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

даже PermGen GC собирается путем добавления args, таких как-XX:+CMSClassUnloadingEnabled, тогда что делает MetaSpace лучше, чем PermGen?

улучшение с динамическим расширением metaspace которое есть что-то, чего пермген не мог сделать.

MetaSpace основан на собственной памяти, поэтому он сохраняет объекты java на дисках, а не на VM?

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

на основе исследования Пьера-Хьюза Шарбонно (ссылка здесь) ясно, что введение metaspace не обязательно решает проблему OOM, в лучшем случае это бандаж для проблемы, он пытается динамически изменять размер памяти metaspace для размещения растущего числа классов, которые загружаются с возможным побочным эффектом бесконтрольного роста (пока это позволяет собственная память).

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

большое спасибо Pierre-Hugues Шарбонно.

по умолчанию память Metaspace собирается, если она достигает MaxMetaspaceSize. Этот параметр изначально не ограничен. Лимит память в вашей машине. Но память автоматически freeded для класса А и загрузчик уже не нужен. Вам нужно настроить этот параметр, только если вы подозреваете, что загрузчик классов имеет утечку памяти.

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

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

Если вы установите параметр MaxMetaspaceSize, вы можете получить OutOfMemory и, если вы не установите этот параметр, вы можете получите, если процесс выделит всю память машины (включая пространство подкачки).

является ли MetaSpace по умолчанию GC собранным?

сборка мусора мертвых классов и загрузчиков классов запускается, как только использование метаданных класса достигает «MaxMetaspaceSize», который по умолчанию является «unlimited» поэтому необходим правильный контроль для ограничения задержки или частоты такого GC.

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

MetaSpace основан на собственной памяти, поэтому он сохраняет объекты java на дисках, а не на VM?

диск-это не собственная память, а запоминающее устройство. Собственная память, в этом контексте является областью, является памятью для процесса, оставшегося от Java кучи

даже MetaSpace может закончиться память?

Да, он ограничен объемом памяти в вашей машине.

Источник

Permgen vs Metaspace в Java

Узнайте о различиях между областями памяти PermGen и Metaspace в Java

1. введение

В этом кратком руководстве мы рассмотрим различия между областями памяти PermGen и метапространства в среде Java.

Важно иметь в виду, что, начиная с Java 8, метапространство заменяет PermGen, внося некоторые существенные изменения.

2. ПермГен

JVM отслеживает загруженные метаданные класса в PermGen. Кроме того, JVM хранит все статическое содержимое в этом разделе памяти. Это включает в себя все статические методы, примитивные переменные и ссылки на статические объекты.

Максимальный размер памяти по умолчанию для 32-разрядной JVM составляет 64 МБ, а для 64-разрядной версии-82 МБ.

Однако мы можем изменить размер по умолчанию с помощью параметров JVM:

Самое главное, что Oracle полностью удалил это пространство памяти в выпуске JDK 8. Поэтому, если мы используем эти флаги настройки в Java 8 и более новых версиях, мы получим следующие предупреждения:

Поэтому мы получаем ошибку пространства памяти ; это происходит в основном в среде разработки при создании новых загрузчиков классов.

Читайте также:  какой компрессор лучше для газели

3. Метапространство

У нас также есть новые флаги для настройки памяти:

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

Несмотря на все эти улучшения, нам все еще необходимо отслеживать и настраивать метапространство, чтобы избежать утечек памяти.

4. Резюме

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

PermGen по-прежнему работает с JDK 7 и более старыми версиями, но Metaspace предлагает более гибкое и надежное использование памяти для наших приложений.

Источник

Metaspace

Note: this Wiki page describes Metaspace in its current form, which has substantially changed in the wake of JEP 387 Elastic Metaspace. Some information in this page may not be applicable for earlier JDK releases.

What is Metaspace?

Metaspace is a native (as in: off-heap) memory manager in the hotspot.

High-level functional overview

Globally there exist a `MetaspaceContext`: it manages the underlying memory at the OS level. To arenas it offers a coarse-grained allocation API, which hands out memory in the form of chunks. It also keeps a freelist of said chunks which had been released from deceased arenas.

Only one global context exists if compressed class pointers are disabled and we have no compressed class space. If compressed class pointers are enabled, we keep class space allocations separate from non-class space allocations. So we have two global metaspace contexts: one holding allocations of Klass structures (the «compressed class space»), one holding everything else (the «non-class» metaspace). Mirroring that duality, each CLD now owns two arenas as well.

No compressed class space:

With compressed class space enabled, we have two Metaspace contexts (one normal, one wrapping the class space), and each CLD has now two arenas, one associated with non-class context, one with the class space.

In this mode, memory for Klass structures is allocated from the class space, all other metaspace allocations from the non-class metaspace:

Core Concepts

Commit Granules

One of the key points of Elastic Metaspace is elasticity, the ability to return unneeded memory to the OS, and commit memory only on demand.

Metaspace address space is divided into homogeneously power-of-two sized memory units called commit granules. Commit granules are the basic unit of committing and uncommitting memory in Metaspace and therefore dictate the coarseness of committing.

While commit granules may be technically as small as a single page, in practice they are larger (defaulting to 64K). When memory is returned to the metaspace, commit granules which are completely unoccupied are uncommitted.

The commit granule size is a trade-off between efficiency of memory reclamation and certain costs associated with fragmenting the memory map. The smaller a granule is, the more likely it is to be unoccupied and eligible for uncommitting, but at the same time, uncommitting many small areas will increase the number of mappings of the VM process. The default size is 64K, which is a compromise which seems to work very well, only moderately increase the number of mappings while giving us good elasticity.

Granule size can indirectly be influenced via the MetaspaceReclaimStrategy switch (see below).

Metachunks and the Buddy Style Allocator

Metaspace arenas will dynamically grow, in semi-coarse steps. Internally they are lists of variable-sized memory areas called Metachunk (see metachunk.hpp ). Arenas obtain these chunks from their respective metaspace context, to which they return all chunks in bulk when they die.

In buddy style allocation, a chunk is always one part of a neighboring pair of chunks, unless the chunk is a root chunk. In code we use the term leader for the chunk with the lower address of the pair, his partner is called follower.

One or both of which could be split into smaller chunks, of course.

Merging chunks

This crystallizes a range of free chunks into one larger chunk quite effectively. In the following figure, chunk b becomes free, melds with free chunk A, then with chunk C:

Splitting chunks

To get a small chunk from a larger chunk, a large chunk can be split. Splitting happens in power-of-2 sizes. A split operation yields the desired smaller chunk as well as 1-n splinter chunks.

How it all looks in memory

Subsystems

Metaspace implementation is divided into separate sub systems, each of which is isolated from its peers and has a small number of tasks.

The Virtual Memory Subsystem

The Virtual Memory Layer is the lowest subsystem. It forms one half of a metaspace context (the upper half being the chunk manager).

It is responsible for reserving and committing memory. It knows about commit granules. Its outside interface to upper layers is the VirtualSpaceList while some operations are also directly exposed via VirtualSpaceNode.

Essential operations

«Allocate new root chunk»

This carves out a new root chunk from the underlying reserved space and hands it to the caller (nothing is committed yet, this is purely reserved memory).

Читайте также:  что делать если головка закрывается сама

Upper layers request that a given arbitrary address range should be committed. Subsystem figures out which granules would be affected and makes sure those are committed (which may be a noop if they had been committed before).

When committing, subsystem honors VM limits ( MaxMetaspaceSize resp. the commit gc threshold) via the commit limiter.

«uncommit this range»

Similar to committing. Subsystem figures out which commit granules are affected, and uncommits those.

This unmaps all completely empty memory regions, and uncommits all unused commit granules.

Other operations

The Virtual Memory Subsystem takes care of Buddy Allocator operations, on behalf of upper regions:

Classes

VirtualSpaceList

The non-expandable latter case is used to represent the class space, which has to be a single contiguous address range for compressed Klass* pointer encoding to work. In that case, the class-space VirtualSpaceList just contains a single node, which wraps the whole of the class space. This may sound complicated but is just a matter of code reuse.

VirtualSpaceNode

VirtualSpaceNode ( virtualSpaceNode.hpp) manages one contiguous memory mapping for Metaspace. In case of the compressed class space, this encompasses the whole pre-reserved address range of the class space. In case of the non-class metaspace, these are smallish mappings, by default two root chunks in size.

VirtualSpaceNode knows about commit granules, and it knows which commit granules in it are commited (via the commit mask).

VirtualSpaceNode also knows about root chunks: its memory is divided into a series of root-chunk-sized areas ( class RootChunkArea ). To keep coding simple, we require each memory mapping to be aligned to root chunk size in both start address and size.

Note: the concepts of chunks and of commit granules are almost completely independent from each other. The former is a means of handing out/taking back memory while avoiding fragmentation; the latter a way to manage commit state of memory.

Putting this all together, the memory underlying a VirtualSpaceNode looks like this:

CommitMask

Just a bit mask inside a VirtualSpaceNode holding commit information (one bit per granule).

RootChunkArea and RootChunkAreaLUT

RootChunkArea contains the buddy allocator code. It is wrapped over the area of a single root chunk.

It knows how to split and merge chunks. It also has a reference to the very first chunk in this area (needed since Metachunk chunk headers are separate entities from their payload, see below, and it is not easy to get from the metaspace start address to its Metachunk ).

CommitLimiter

When committing memory for Metaspace, we have to observe two limits:

Источник

Java 8: от PermGen к MetaSpace

(Сокращённый перевод статьи Пьера-Хьюза Шарбонне)

Как уже сообщалось ранее на Java One, в Java 8 версии HotSpot планируется отказаться от PermGen пространства в пользу новой его вариации — Metaspace. Ранний доступ к JDK 8 даёт возможность наблюдать Metaspace в действии, чем и воспользовался автор оригинальной статьи чтоб узнать, какие преимущества даёт MetaSpace в сравнении с PermGen, и убедится во всём непосредственно.

Подробнорсти под катом.

Что такое Metaspace

В рамках мерджа HotSpot с JRockit хранение метаданных о классах будет осуществляться в нативной памяти, по аналогии с JRockit и IBM JVM. Часть нативной памяти, отведённая под эти метаданные, носит название Metaspace.

Итак, Metaspace это замена PermGen, основное отличие которой с точки зрения Java-программистов — возможность динамически расширятся, органиченная по умолчанию только размером нативной памяти. Параметры PermSize и MaxPermSize отныне упразднены (получив эти параметры JVM будет выдавать предупреждение о том, что они более не действуют), и вместо них вводится опциональный параметр MaxMetaspaceSize, посредством которого можно задать ограничение на размер Metaspace.

В результате максимальный Metaspace по умолчанию не ограничен ничем кроме предела объёма нативной памяти. Но его можно по желанию ограничить параметром MaxMetaspaceSize, аналогичным по сути к MaxPermSize.

Предполагается, что таким образом можно будет избежать ошибки «java.lang.OutOfMemoryError: PermGen space» за счёт большей гибкости динамического изменения размера Metaspace. Но, конечно, если размер Metaspace достигнет своей границы — будь то максимум объёма нативной памяти, или лимит заданный в MaxMetaspaceSize — будет выброшено аналогичное исключение: «java.lang.OutOfMemoryError: Metadata space».

Сборка мусора

Логи Garbage Collector-а будут сообщать также и о сборке мусора в Metaspace.

Сама сборка мусора, если верить автору статьи, будет происходить при достижении Metaspace размера, заданного в MaxMetaspaceSize. Но его же эксперименты (см. ниже) показывают, что когда MaxMetaspaceSize не задан, сборка мусора в Metaspace тоже осуществляется перед каждым его динамическим увеличением.

Эксперименты

В оригинальной статье автор также приводит графики использования памяти и логи Garbage Collector-а — для тех кому это интересно. Графики и логи должны быть понятны без перевода.

От себя добавлю, что такое нововведение может быть полезно для запуска java кода на клиентских машинах. Например ant/maven билд скриптов, которым ранее иногда приходилось поднимать MaxPermSize для успешного завершения билда. А также будет весьма полезно в тех (пусть и редких) случаях, когда используются десктопные Java приложения, оганичение PermGen для которых никогда не имело особого смысла.

Источник

Сказочный портал