Слабая ссылка на объект, содержащий вложенную сильную ссылку и сбор мусора
Предположим, что у меня есть слабая ссылка на автомобиль, который имеет обычную (сильную) ссылку на двигатель. Никаких других ссылок на автомобиль или двигатель не существует. Может ли сборщик мусора собираться?
Ответы
Ответ 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());
}
}