Предпосылка вашего теста ошибочна.System.gc()
- это всего лишь подсказка для запуска сборщика мусора.Это часто игнорируется.
Из документации :
Вызов метода gc предполагает , что виртуальная машина Java затрачивает усилия на утилизацию неиспользуемых объектов, чтобысделайте память, которую они занимают в настоящее время доступной для быстрого повторного использования.Когда управление возвращается из вызова метода, виртуальная машина Java сделала все возможное, чтобы освободить пространство от всех отброшенных объектов.
(выделение мое)
В будущем вы можете использоватьопции VM -verbose:gc
и -XX:+PrintGCDetails
, чтобы увидеть, что делает сборщик мусора.
Что еще более важно, вы также очень быстро извлекаете ссылку из слабой ссылкии вернем его обратно в строгую ссылку:
A a = new A();
WeakReference<A> wr = new WeakReference<>(a);
a = null; // no strong references remain
A a1 = wr.get(); // the instance now has a strong reference again
Если между этими двумя точными инструкциями не происходит сборка мусора, объект не будет собирать мусор.
Если вы удалите a1
, вашкод вел себя так, как вы ожидаете, когда я его запустил (хотя из-за первой части моего ответа ваш пробег может отличаться):
class A
{
public static void main(String[] args)
{
A a = new A();
WeakReference<A> wr = new WeakReference<>(a);
a = null;
System.out.println(a);
try {
System.gc(); // instance of A is garbage collected
Thread.sleep(10000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(wr.get());
}
@Override
protected void finalize( )
{
System.out.println(Thread.currentThread().getName() + ": See ya, nerds!");
}
}