2017-01-31 16 views
1

В следующем фрагменте (единственная цель которого - образовательное тестирование), всегда ↲ истинно.Есть ли способ проверить, когда элемент удален из слабого набора?

Set<String> weakSet = Collections.newSetFromMap(new WeakHashMap<>()); 
    weakSet.add("someKey"); 
    System.gc(); 
    weakSet.contains("someKey"); 

Я бы ожидать, что best effort сделано с помощью виртуальной машины Java, чтобы освободить пространство включает в себя удаление объектов, которые слабо достижимый (слабый набор элементы без каких-либо сильных ссылок). Но я ошибаюсь.

Итак, есть ли способ проверить на практике автоматическое удаление слабых ссылок, чтобы вы могли видеть, что ссылка ушла? Другими словами, как вернуть false?

+2

Причина, по которой snippet всегда возвращает 'true', потому что [' String' литералы обычно не собираются с мусором] (https://stackoverflow.com/questions/15324143/garbage-collection-of-string-literals). –

ответ

2

Как @Chai T.Rex правильно упоминается в комментариях, строки являются плохим примером для сбора мусора. Чтобы увидеть, как объекты мусор из слабого набора попробуйте эту модифицированную версию кода:

Set<Object> weakSet = Collections.newSetFromMap(new WeakHashMap<>()); 
    weakSet.add(new Object()); 
    System.out.println(weakSet.size()); // prints "1" 
    while (weakSet.size() > 0) 
     System.gc(); 
    System.out.println(weakSet.size()); // prints "0" 

Что вообще здесь происходит: мы добавляем новый объект в набор (weakSet.add(new Object())). Но поскольку мы не будем ссылаться на него, GC обнаружит, что этот объект будет удален из набора.

Петля на GC необходима, так как сбор мусора в этом простом примере случая не гарантируется.

+0

Определенно ответ. Спасибо за просветление! – ARX

+1

... или вы меняете вторую строку исходного кода на 'weakSet.add (новый String (« someKey »));' – Holger

+0

@Holger, хорошая идея. Но, похоже, это немного интуитивно. – Andremoniy