Java metaspace что это

Введение в Java Process Memory Model

Каждое Java приложение, после запуска, создаёт десятки, сотни, тысячи объектов в памяти компьютера на котором оно запущено. Память, при этом, ресурс не бесконечный, и поэтому необходимо использовать его эффективно. Виртуальная Машина Java (Java Virtual Machine, далее JVM) умеет граммотно распоряжаться памятью и помогает нам, разработчикам, управляя ею автоматически.

О том, как именно JVM работает с памятью во время работы Java приложения мы поговорим в этой статье.

Каждое Java приложение, после запуска, создаёт десятки, сотни, тысячи объектов в памяти компьютера на котором оно запущено. Память, при этом, ресурс не бесконечный, и поэтому необходимо использовать его эффективно. Виртуальная Машина Java (Java Virtual Machine, далее JVM) умеет граммотно распоряжаться памятью и помогает нам, разработчикам, управляя ею автоматически.

О том, как именно JVM работает с памятью во время работы Java приложения мы поговорим в этой статье.

Зачем вообще разработчику знать о памяти Java процесса?

Java — это язык программирования с автоматическим управлением памятью.

Очень хороший вопрос. Действительно, Java — язык с автоматическим управлением памятью. Разработчику вообще можно ничего не знать о том, как JVM работает с ней. Но — можно ли с уверенностью сказать, что разработчик не влияет на работу его приложения с памятью? Нет, конечно же — нет.

Читайте также:  Светофор

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

Память Java процесса

Память, выделяемая Java процессу, представляет из себя набор из двух областей:

Каждая из областей имеет собственное предназначение.

Metaspace

Metaspace — это область памяти в которой хранится статическая инфорация Java приложения, такая как метаданные загруженных классов. По умолчанию, metaspace увеличивается автоматически и не имеет явного ограничения. Без установленного ограничения размер metaspace неявно ограничен объёмом системной памяти хоста.

Управление Metaspace

Управлять metaspace областью можно с помощью следующих флагов JVM:

  • -XX:MetaspaceSize — минимальный объём памяти для области
  • -XX:MaxMetaspaceSize — максимальный объём памяти для области
  • -XX:MinMetaspaceFreeRatio — минимально зарезервированный размер памяти после очистки GC (в процентах)
  • -XX:MaxMetaspaceFreeRatio — максимально зарезервированный размер памяти после очистки GC (в процентах)

Heap

Heap — это область памяти в которой хранятся инстансы объектов. Каждый раз, когда разработчик создаёт инстанс какого-либо класса с помощью операции new (пример: new Object() ), память под объект выделяется именно в heap’е.

Строковый пул, так же, начиная с Java 7 располагается в heap’е.

Heap, в свою очередь, содержит несколько подобластей, каждая из которых выполняет свою определённую роль. Поговорим о них подробнее. Следующие подобласти относятся к heap’у:

Eden

Это сегмент heap области в который свежесозданные объекты попадают в первую очередь. Каждый раз, когда в Java приложении выполняется инструкция new , память, выделяемая под новый инстанс, выделяется именно в Eden сегменте.

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

Надолго свежесозданные объекты в Eden сегменте не задержатся. После первого же запуска процесса сборки мусора, они либо будут удалены из памяти, либо будут перенесены в Survival сегменты heap’а.

S0 и S1 — Survival

Survival сегмент области heap’а используется JVM для хранения объектов, которые пережили один и более проходов сборщика мусора.

Survival сегмент представлен в JVM двумя сегментами — S0 и S1. Они служат неким «перевалочным пунктом» для объектов на пути к Old Gen сегменту. В S0 и S1 сегментах объекты могут провести какое-то время до тех пор, пока они не будут удалены из памяти или переведены в Old Gen сегмент.

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

Почему Survival область представлена двумя сегментами S0 и S1? Всё дело в том, что для ускорения очистки памяти и исправления её фрагментации, в ходе процесса сборки мусора два этих сегмента дефрагминтируются и меняются местами.

Old Gen

Old Gen сегмент heap’а используется для хранения объектов, которые пережили установленное количество запусков сборки мусора.

Полная схема памяти Java процесса выглядит следующим образом:

Управление Heap

Управлять heap областью можно с помощью следующих флагов JVM:

  • -Xms — минимальный объём памяти всей области
  • -Xmx — максимальный объём памяти всей области
  • -XX:NewSize — минимальный объём памяти Eden сегмента
  • -XX:MaxNewSize — максималный объём памяти Eden сегмента
  • -XX:SurvivorRatio — соотношение между объёмами памяти Eden и Survival сегментов

Зачем использовать разные области и сегменты памяти? Потому что это позволяет организовать процесс сборки мусора наиболее оптимальным образом для каждого из сегментов, с учётом специфики каждого.

Где это может пригодиться?

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

Если Вы заметили, что Вашего приложение неотзывчиво в некоторых сценариях или в целом, то первое на что стоит обратить внимание, так это на то, как Ваше приложение распоряжается отведённой ему памятью. Сделать это можно, например, с помощью VisualVM — бесплатной утилиты для мониторинга JVM приложений.

Заключение

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

Работа JVM с памятью непосредственно связана с такой сложной темой как сборка мусора. И сегодня Вы сделали первый шаг на пути к пониманию потаённой стороны Java.

Список материалов

Дополнительные источники информации о коммуникациях, могут быть найдены в следующих источниках:

  • «Презентация Troubleshooting Memory Issues in Java Applications» — краткое пояснение имеющихся областей памяти JVM.
  • «Гайд по флагам JVM» — список полезных флагов JVM с пояснением.
  • «HotSpot Virtual Machine Garbage Collection Tuning Guide» — официальный документ от Oracle о настройке сборщиков мусора. В нём можно найти описания областей памяти и их сегментов.

Ещё материалы по теме

Источник

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 тоже осуществляется перед каждым его динамическим увеличением.

Эксперименты
  • JDK 1.7, MaxPermSize = 128 MB
  • JDK 1.8 (b75), MaxMetaspaceSize не задан
  • JDK 1.8 (b75), MaxMetaspaceSize = 128 MB
  • при MaxPermSize = 128 MB на JDK 1.7 ему удалось загрузить чуть более 30 тысяч классов до выбрасывания исключения «OutOfMemoryError: PermGen space».
  • при отсутствии лимита MaxMetaspaceSize на JDK 1.8 его программа загрузила 50 тысяч классов (больше он не пробовал) без получения исключений
  • при лимите MaxMetaspaceSize в 128 MB на JDK 1.8 результат был аналогичен MaxPermSize = 128 MB на JDK 1.7 — удалось загрузить чуть более 30 тысяч классов до выбрасывания исключения «OutOfMemoryError: Metadata space»

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

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

Источник

Оцените статью