Создание объекта и выделение памяти

Java

создать объект

когда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, и заинтересованные друзья могут поддерживать их вместе.

адрес:GitHub.com/crossover J я…