Слабая ссылка на объект, содержащий вложенную сильную ссылку и сбор мусора

Предположим, что у меня есть слабая ссылка на автомобиль, который имеет обычную (сильную) ссылку на двигатель. Никаких других ссылок на автомобиль или двигатель не существует. Может ли сборщик мусора собираться?

Ответы

Ответ 1

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

Для получения дополнительной информации см. WeakReference:

Слабые ссылочные объекты, которые не препятствовать их референтам быть был завершен, финализирован, а затем утилизирован. Слабые ссылки часто используется для реализации канонизации отображения.

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

FYI, наряду с WeakReference, Java предлагает два других подкласса Reference: SoftReference и PhantomReference.

Ответ 2

Экземпляром Car может быть собран мусор, но нет никакой гарантии, что это будет сбор мусора в следующем цикле GC или даже что он будет собран вообще. Например,

  • В какое-то время до запуска GC приложение get может вызвать WeakReference и сохранить ссылку на Car в (например) атрибут некоторого объекта с достижением. Экземпляр Car затем становится полностью доступным и больше не имеет права на сбор мусора.

  • Если GC работает с Car в описанном состоянии, спецификация JVM не гарантирует, что слабодоступный будет обнаружен в следующем цикле GC. Например, если данный цикл GC собирает только последнее поколение (и Car был переведен в более старшее поколение), GC не будет определять, что он слабо доступен.

  • Даже когда GC разбивает ссылку на Car в WeakReference, экземпляр Car не восстанавливается немедленно. Скорее, восстановление более недоступного Car, вероятно, произойдет (после возможной финализации) в более позднем цикле GC.

Ответ 3

Здесь a unit test, который демонстрирует слабые ссылки. Обратите внимание: System.gc() не гарантирует, что объект получит сбор мусора, и вы не должны полагаться на него.

import junit.framework.TestCase;

import java.lang.ref.WeakReference;

public class WeakReferenceTest extends TestCase {


    class Car {

        Engine engine = new Engine();

    }

    class Engine {

    }

    public void testWeakReferences() {
        WeakReference<Car> carRef = new WeakReference<Car>(new Car());
        assertNotNull(carRef.get());
        System.gc();
        assertNull(carRef.get());
    }

}