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