Каковы корни? - PullRequest
       50

Каковы корни?

62 голосов
/ 16 июня 2011

Каковы корни в сборке мусора?

Я прочитал определение root как «любую ссылку, к которой вы можете запрограммировать доступ», а определение live - это используемый объект, который можетбыть локальной переменной, статической переменной.

Меня немного смущает различие между корнем и живыми объектами.

Что такое путь к корню?Как работают корневые и живые объекты?

Может кто-нибудь уточнить?

Ответы [ 5 ]

85 голосов
/ 16 июня 2011

Если вы думаете об объектах в памяти как о дереве, «корнями» будут корневые узлы - каждый объект, непосредственно доступный вашей программе.

Person p = new Person();
p.car = new Car(RED);
p.car.engine = new Engine();
p.car.horn = new AnnoyingHorn();

Есть четыре объекта; человек, красная машина, ее двигатель и гудок. Нарисуйте контрольный график:

     Person [p]
        |
     Car (red)
   /           \
Engine    AnnoyingHorn

И вы получите Person в «корне» дерева. Он активен, потому что на него ссылается локальная переменная p, которую программа может использовать в любое время для ссылки на объект Person. Это также относится и к другим объектам, через p.car, p.car.engine и т. Д.

Поскольку Person и все другие объекты, рекурсивно связанные с ним, являются живыми, возникнет проблема, если GC соберет их.

Учтите, однако, если через некоторое время выполняется следующее:

p.car = new Car(BLUE);

И перерисовать график:

     Person [p]
        |
     Car (blue)       Car (red)
                    /           \
                Engine    AnnoyingHorn

Теперь Person доступен через p, а синяя машина - через p.car, но нет никакой возможности снова получить доступ к красной машине или ее частям - они не подключены к живому корню. Их можно безопасно собрать.

Так что это действительно вопрос выбора каждой начальной точки (каждой локальной переменной, глобальных переменных, статики, всего в других потоках и фреймах стека) - каждого корня - и рекурсивного следования всем ссылкам, чтобы составить список всех "живых" "объекты: объекты, которые используются и не подходят для удаления. Все остальное - мусор, ожидающий сбора.

35 голосов
/ 15 марта 2013

Корни GC (Сборщик мусора) - это объекты, специально предназначенные для сборщика мусора. Сборщик мусора собирает те объекты, которые не являются корнями GC и не доступны по ссылкам от корней GC.

Существует несколько видов корней ГК. Один объект может принадлежать более чем одному виду корня. Коренные виды:

  • Class - класс, загружаемый системным загрузчиком классов. Такие классы никогда не могут быть выгружены. Они могут содержать объекты через статические поля. Обратите внимание, что классы, загружаемые пользовательскими загрузчиками классов, не являются корнями, если только соответствующие экземпляры java.lang.Class не являются корнями других типов.
  • Thread - живая тема
  • Stack Local - локальная переменная или параметр метода Java
  • JNI Local - локальная переменная или параметр метода JNI
  • JNI Global - глобальная ссылка на JNI
  • Используемый монитор - объекты, используемые в качестве монитора для синхронизации
  • Удерживается JVM - объекты, которые JVM хранит из сборки мусора для своих целей. На самом деле список таких объектов зависит от реализации JVM. Возможные известные случаи: загрузчик системных классов, несколько важных классов исключений, о которых знает JVM, несколько предварительно выделенных объектов для обработки исключений и пользовательские загрузчики классов, когда они находятся в процессе загрузки классов. К сожалению, JVM не предоставляет абсолютно никаких дополнительных деталей для таких объектов. Таким образом, аналитик должен решить, к какому случаю относится некий «Удерживаемый JVM».

(кредит на сайте YourKit )

YourKit не упоминает тот факт, что объекты, ожидающие завершения, будут сохранены как корни, пока GC не выполнит метод finalize(). Это может неожиданно вызвать временное удержание больших графов. Основное правило - не использовать финализаторы (но это другой вопрос).

29 голосов
/ 16 июня 2011

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

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

Я знаю Java больше, чем платформа .Net, поэтому я буду говорить только об одном.На платформе Java корни GC фактически зависят от реализации.Однако в большинстве сред выполнения корни GC обычно являются операндами в стеке (поскольку они в настоящее время используются потоками) и классовыми (статическими) членами классов.Достижимость рассчитывается из этих объектов в большинстве JVM.Есть и другие случаи, когда локальные параметры и операнды, используемые вызовами JNI, будут считаться частью корневого набора, а также использоваться для вычисления достижимости.

Я надеюсь, что это устранит все оставшиеся сомнения относительно того, что является корнем (набор)и что такое живой объект.

14 голосов
/ 21 января 2015

На веб-сайте IBM перечислено следующее как корни GC.

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

  • Системный класс

    Класс, который был загружен загрузчиком начальной загрузки или загрузчиком системного класса.Например, в эту категорию входят все классы в файле rt.jar (часть среды выполнения Java), например, в пакете java.util. *.

  • JNI local

    Локальная переменная в собственном коде, например, определяемый пользователем код JNI или внутренний код JVM.

  • JNI global

    Глобальная переменная в собственном коде, например, определяемый пользователем код JNI или внутренний код JVM.

  • Блок потока

    Объект, на который ссылались из активного блока потока.

  • Резьба

    Работающий поток.

  • Занятый монитор

    Все, что вызывало методы wait () или notify () или синхронизировано, например, путем вызова метода synchronized (Object) или путем ввода синхронизированногометод.Если метод был статическим, корень является классом, в противном случае это объект.

  • Java local

    Локальная переменная.Например, входные параметры или локально созданные объекты методов, которые все еще находятся в стеке потока.Собственный стек

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

  • Финализатор

    Объект, находящийся в очереди, ожидая запуска финализатора.

  • Нефинализированный

    Объект, который имеет метод финализации, но еще не завершен и еще не завершенв очереди финализатора.

  • Недоступен

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

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

    По умолчанию недоступные объекты исключаются, когда анализатор памяти анализирует дамп кучи.Следовательно, эти объекты не отображаются в гистограмме, в дереве доминирования или в результатах запроса.Вы можете изменить это поведение, щелкнув Файл> Настройки ...> IBM Diagnostic Tools for Java - Memory Analyzer, затем установив флажок Сохранить недоступные объекты.

  • фрейм стека Java

    Фрейм стека Java, содержащий локальные переменные.Этот тип корня сборки мусора генерируется только в том случае, если вы задаете настройки для обработки фреймов стека Java как объектов.Для получения дополнительной информации см. Основы Java: потоки и запросы стека потоков.

  • Неизвестно

    Объект неизвестного корневого типа.Некоторые дампы, такие как файлы IBM Portable Heap Dump (.phd), не имеют корневой информации.В этом случае анализатор Memory Analyzer помечает объекты, которые не имеют входящих ссылок или недоступны из любого другого корня, как неизвестные.Это действие гарантирует, что Memory Analyzer сохранит все объекты в дампе.

3 голосов
/ 16 июня 2011

В Java я бы сказал, что потоки являются корневыми объектами. Каждый живой объект может быть возвращен в текущий поток. Например, на статический объект ссылается класс, на который ссылается загрузчик класса, на который ссылается другой класс, на который ссылается экземпляр этого класса, ... на который ссылается Runnable, на который ссылается живой веткой. ( Обратите внимание, что классы могут быть GC'едами, они не могут быть корнями )

Мы также можем рассмотреть «настоящий» корень для всех потоков, однако это выходит за рамки стандартной Java. Мы не можем сказать, что это такое и как оно ссылается на все темы.

...