Как отмечают другие, нет гарантии, что System.gc()
выполняет фактическую сборку мусора.Также не гарантирован цикл сбора мусора для фактического сбора определенного недоступного объекта.
Но в вашей конкретной настройке кажется, что System.gc()
достаточно для сбора объекта, как определено вашим примером WeakReference
.Но очистка слабой ссылки - это не то же самое, что очистка ссылки, чтобы позволить WeakHashMap
выполнить ее очистку.Как объяснено в этом ответе , очистка WeakHashMap
зависит от ключевой ссылки, которая будет поставлена в очередь, которая будет проверяться каждый раз, когда вы вызываете метод для него, который является последующим map.size()
Вызов в вашем примере.
Как и , документация WeakReference
указывает:
Предположим, что сборщик мусора определяет в определенный момент времени, что объектслабо достижим.В это время он будет атомарно очищать все слабые ссылки на этот объект и все слабые ссылки на любые другие слабо достижимые объекты, из которых этот объект доступен через цепочку сильных и мягких ссылок.В то же время он объявит, что все ранее слабо достижимые объекты были завершены.В то же время или в более позднее время он будет ставить в очередь те недавно очищенные слабые ссылки, которые зарегистрированы в очередях ссылок.
Обратите внимание, как происходит очистка « в это время », тогда какпостановка в очередь произойдет « в то же время или в более позднее время ».
В случае HotSpot JVM / OpenJDK постановка в очередь происходит асинхронно после сборки мусора, и кажется, что ваш основной поток тоже работаетбыстро, поэтому ссылка на ключ еще не была поставлена в очередь.
Вставка небольшой паузы может привести к успешному выполнению примера программы в типичных условиях:
import java.util.WeakHashMap;
public class Main2 {
public static void main(String[] args) throws InterruptedException{
String name = new String("ltt");
WeakHashMap<String, Integer> map = new WeakHashMap<>();
map.put(name, 18);
System.out.println(map.size()); // 1
name = null;
System.gc();
Thread.sleep(10);
System.out.println(map.size()); // 0
}
}
Конечно, это не изменитсятот факт, что это удобно для тестирования, но не гарантирует гарантированного поведения, поэтому не следует писать производственный код, опираясь на него.