Каковы корни?
Каковы корни в сборке мусора?
Я прочитал определение root как "любую ссылку, к которой вы можете обращаться", а определение live - это то, что используется объект, который может быть локальной переменной, статической переменной.
Я немного путаюсь с различием различий между корневыми и живыми объектами.
Что такое путь к корню? Как работают коренные и живые объекты?
Может кто-нибудь уточнить?
Ответы
Ответ 1
Если вы думаете об объектах в памяти как о дереве, то "корнями" будут корневые узлы - каждый объект, сразу доступный вашей программе.
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
, но красный автомобиль или его части не могут быть снова доступны - они не подключены к живому корню. Их можно безопасно собрать.
Таким образом, на самом деле речь идет о каждой отправной точке (каждая локальная переменная, глобалы, статика, все в других потоках и стеках) - каждый корень - и рекурсивно следуя всем ссылкам, чтобы составить список всех "живых" "объекты: объекты, которые используются и непригодны для удаления. Все остальное - мусор, ожидающий сбора.
Ответ 2
Корзины GC (Garbage Collector) - это объекты, специально предназначенные для сборщика мусора. Сборщик мусора собирает те объекты, которые не являются корнями GC и недоступны по ссылкам из корней GC.
Существует несколько видов GC-корней. Один объект может принадлежать более чем одному виду корня. Типы корней:
- Класс - класс, загруженный загрузчиком системного класса. Такие классы никогда не могут быть выгружены. Они могут содержать объекты через статические поля. Обратите внимание, что классы, загруженные пользовательскими загрузчиками классов, не являются корнями, если соответствующие экземпляры java.lang.Class не являются корнями другого типа.
- Тема - живая тема
- Stack Local - локальная переменная или параметр метода Java
- JNI Local - локальная переменная или параметр метода JNI
- JNI Global - глобальная ссылка JNI
- Используемый монитор - объекты, используемые в качестве монитора для синхронизации
- Содержит JVM - объекты, предназначенные для сбора мусора JVM для его целей. Фактически список таких объектов зависит от реализации JVM. Возможными известными случаями являются: загрузчик системного класса, несколько важных классов исключений, о которых знает JVM, несколько предварительно выделенных объектов для обработки исключений и пользовательские загрузчики классов, когда они находятся в процессе загрузки классов. К сожалению, JVM не предоставляет абсолютно никакой дополнительной информации для таких объектов. Таким образом, аналитик должен решить, к какому случаю принадлежит определенный "Held by JVM".
(кредит веб-сайт YourKit)
Не упоминается YourKit в том, что объекты, ожидающие завершения, будут сохраняться как корни, пока GC не выполнит метод finalize()
. Это может вызвать временное сохранение больших графиков несколько неожиданно. Общее эмпирическое правило - не использовать финализаторы (но это другой вопрос).
Ответ 3
Корни корней или мусора - это объекты, которые всегда достижимы. Если объект всегда доступен, он не имеет права на сбор мусора; поэтому корни поэтому не имеют права на сбор. Это начальный набор объектов, из которых определяются достижимость всех других объектов в куче.
Другие объекты в куче, достигаемые из корней сбора мусора, считаются живыми объектами и не пригодны для сбора; объекты, которые недоступны, могут быть помечены для рекультивации.
Я знаю Java больше, чем платформа .Net, поэтому я буду говорить только за одного. На платформе Java корни GC на самом деле зависят от реализации. Однако в большинстве случаев корни GC обычно являются операндами в стеке (в настоящее время они используются в потоках) и классами (статическими) классами. Достижимость рассчитывается из этих объектов в большинстве JVM. Существуют и другие случаи, когда локальные параметры и операнды, используемые вызовами JNI, будут считаться частью набора корней, а также использоваться для расчета достижимости.
Надеюсь, это устранит любые затяжные сомнения в отношении того, что является корнем (set) и тем, что является живым объектом.
Ответ 4
В веб-сайте IBM перечислены следующие корни GC.
Обратите внимание, что некоторые из них - это искусственные конструкции, выполняемые анализатором памяти, но все же важно знать, смотрите ли вы на кучу кучи.
-
Класс системы
Класс, загруженный загрузчиком начальной загрузки или загрузчиком системного класса. Например, эта категория включает все классы в файле rt.jar(часть среды выполнения Java), например, в пакете java.util. *.
-
JNI local
Локальная переменная в собственном коде, например пользовательский код JNI или внутренний код JVM.
-
JNI global
Глобальная переменная в собственном коде, например пользовательский код JNI или внутренний код JVM.
-
Блок потоков
Объект, на который ссылается активный блок потока.
-
Тема
Текущая нить.
-
Занятый монитор
Все, что вызвало методы wait() или notify(), или которые синхронизированы, например, путем вызова метода synchronized (Object) или путем ввода синхронизированного метода. Если метод был статическим, корнем является класс, в противном случае это объект.
-
Java локальный
Локальная переменная. Например, входные параметры или локально созданные объекты методов, которые все еще находятся в стеке потока.
Собственный стек
Входные или выходные параметры в собственном коде, например пользовательский код JNI или внутренний код JVM. Многие методы имеют собственные части, а объекты, которые обрабатываются как параметры метода, становятся корнями сбора мусора. Например, параметры, используемые для операций с файлами, сетями, ввода-вывода или отражения.
-
Финалайзер
Объект, находящийся в очереди, ожидающий выполнения финализатора.
-
незакрытого
Объект, который имеет метод finalize, но не был финализирован и еще не находится в очереди финализатора.
-
Недоступен
Объект, который недоступен из любого другого корня, но был помечен как корень в Memory Analyzer, чтобы объект мог быть включен в анализ.
Недостижимые объекты часто являются результатом оптимизации в алгоритме сбора мусора. Например, объект может быть кандидатом на сбор мусора, но быть настолько мал, что процесс сбора мусора будет слишком дорогим. В этом случае объект может не быть собранным мусором и может оставаться недоступным объектом.
По умолчанию недопустимые объекты исключаются, когда Memory Analyzer анализирует кучу кучи. Поэтому эти объекты не отображаются в гистограмме, дереве доминант или результатах запроса. Вы можете изменить это поведение, щелкнув "Файл" > "Настройки" > "Инструменты диагностики IBM для Java-Memory Analyzer", а затем установите флажок "Сохранить недостижимые объекты".
-
Кадр стека Java
Кадр стека Java, который содержит локальные переменные. Этот тип корня сборщика мусора генерируется только в том случае, если вы задали Preferences для обработки фреймов стека Java как объектов. Дополнительные сведения см. В разделе "Основы Java: потоки и потоки стека".
-
Unknown
Объект неизвестного корневого типа. Некоторые дампы, такие как файлы IBM Portable Heap Dump (.phd), не имеют корневой информации. В этом случае анализатор памяти Analyzer отмечает объекты, которые не имеют входящих ссылок или недоступны из любого другого корня, как неизвестные. Это действие гарантирует, что Memory Analyzer сохраняет все объекты в дампе.
Ответ 5
В java я бы сказал, что потоки - это корневые объекты. Каждый живой объект может быть отслежен до живой нити. Например, статический объект ссылается на класс, на который ссылается загрузчик классов, на который ссылается другой класс, на который ссылается экземпляр этого класса..., на который ссылается Runnable, на который ссылаются по живой нити. (Примечание: классы могут быть GC'ed, они не могут быть корнями)
Мы также можем рассматривать "реальный" корень для всех потоков, однако это выходит за рамки стандартной Java. Мы не можем сказать, что это такое, и как он ссылается на все потоки.