слабая ссылка на объект, содержащий вложенную сильную ссылку и сборщик мусора - PullRequest
16 голосов
/ 06 апреля 2010

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

Ответы [ 3 ]

18 голосов
/ 06 апреля 2010

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

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

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

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

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

8 голосов
/ 06 апреля 2010

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

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

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

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

1 голос
/ 06 апреля 2010

Вот модульный тест, который демонстрирует слабые ссылки.Обратите внимание, что 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());
    }

}
...