создать объект
когдаJVM
получилnew
При выполнении инструкции она проверит, есть ли в параметрах инструкции ссылка на этот символ в пуле констант, а также проверит, вызывался ли класснагрузкаПосле этого, если такового нет, требуется загрузка класса.
Следующим шагом является выделение памяти, обычно двумя способами:
- столкновение указателя
- бесплатный список
Предпосылка использования столкновений указателей заключается в том, что куча памятисовершенно опрятныйДа, используемая память и бесполезная память находятся на одной стороне, каждый раз, когда вы выделяете указатель, вам нужно всего лишь переместить указатель в сторону свободной памяти на область, равную размеру памяти.
Когда используемая память и неиспользуемая память в кучепереплетенныйКогда метод столкновения указателей не будет работать, вам нужно использовать метод свободного списка. Виртуальная машина поддерживает список свободных мест для записи того, какая память может быть выделена, какая может быть выделена непосредственно из доступной памяти.
Память в куче аккуратная?уборщик мусораРешить, использует ли сборщик мусора с функцией сжатия столкновение указателей для выделения памяти.
Проблемы параллелизма также возникают при выделении памяти:
Это можно использовать при создании объектаCAS
Такая оптимистичная блокировка гарантирована.
Также возможно организовать выделение памяти в пространстве, уникальном для каждого потока.Каждый поток сначала выделяет небольшой участок памяти в памяти кучи, называемый локальным кешем распределения (TLAB : Thread Local Allocation Buffer
).
При выделении памяти вам нужно только выделить ее в своем собственном кеше распределения.Так как эта область памяти является приватной для потоков, проблем с параллелизмом не будет.
можно использовать-XX:+/-UseTLAB
параметр, чтобы указать, включена ли JVMTLAB
.
После выделения памяти необходимо установить объект, например заголовок объекта. Некоторые применения заголовков объектов можно просмотретьПринцип синхронизации ключевых слов.
доступ к объекту
После того, как объект создан, он, естественно, используется.В Java стек используется для обращения к объекту в куче памяти для работы.
Для нашего часто используемогоHotSpot
Для виртуальной машины эта ссылочная связь связана с прямым указателем.
Как показано на рисунке:
Преимущество этого в том, что частый доступ к объектам в Java может повысить скорость доступа (по сравнению с использованием пула дескрипторов).
выделение памяти
Распределение зоны Эдема
Проще говоря, объекты размещаются в куче памяти, и, если присмотреться, они имеют приоритет в памяти.Eden
Распределение по районам.
Это включает в себя разделение памяти кучи.Чтобы облегчить сборку мусора, JVM делит память на новое поколение и старое поколение.
Новое поколение будет разделено наEden
округ,from Survivor、to Survivor
Площадь.
вEden
а такжеSurvivor
Масштаб области по умолчанию равен8:1:1
, конечно, также поддерживает настройку параметров-XX:SurvivorRatio=8
.
когда вEden
Возникает при недостаточном объеме памяти, выделенной для зоныminorGC
,из-заJava
Большинство объектов являютсяподниматься и опускатьсяхарактеристики, поэтомуminorGC
Обычно чаще и эффективнее.
когда это произойдетminorGC
, JVM будеталгоритм репликациископировать живой объект в другой неиспользуемыйSurvivor
площадь, еслиSurvivor
Когда в регионе заканчивается память, для перемещения объектов в старое поколение используется стратегия гарантированного выделения.
говоря оminorGC
, надо упомянутьfullGC(majorGC)
, что указывает на возникновениеGC
, как с точки зрения эффективности, так и скорости, чемminorGC
Гораздо медленнее, это все равно произойдет при переработкеstop the world
Вызывает остановку программы, поэтому ее следует избегать, насколько это возможно.fullGC
.
Распределение по старости
Также бывают случаи, когда объекты выделяются непосредственно в старом возрасте, например, при выделении большого объекта (большие массивы, очень длинные строки) из-заEden
Когда в области недостаточно непрерывного пространства для выделения, это вызовет ранний триггер.GC
, поэтому старайтесь не создавать часто большие объекты.
следовательноJVM
В соответствии с пороговым значением объекты, превышающие пороговое значение, будут напрямую отнесены к старому поколению, что позволит избежать частого появления в новом поколении.GC
.
Для некоторых старых объектов в молодом поколенииJVM
Тоже переходит на старое поколение по какому-то механизму.
JVM определяет, следует ли перемещать объект в старое поколение по способу записи возраста объекта.Согласно алгоритму копирования нового поколения, при перемещении объекта вSurvivor
После зоны JVM записывает возраст объекта как 1, и каждый раз, когда он проходит черезminorGC
Возраст более позднего объекта равен +1, пока он не достигнет порога (по умолчанию 15) и не перейдет к старости.
можно использовать
-XX:MaxTenuringThreshold=15
для настройки этого порога.
Суммировать
Хотя это содержимое немного скучно, когда приложение происходит ненормальноGC
, это удобно и быстрее локализовать проблему.
Дополнительный
Недавно я обобщил некоторые знания, связанные с Java, и заинтересованные друзья могут поддерживать их вместе.