2015-04-02 4 views
3

Если я добавляю объекты в HashMap, а затем просто вызываю метод remove, когда они больше не нужны, гарантирует ли он, что ресурсы, которые они берут, будут выпущены (если нет других ссылок на них)?HashMap.remove and garbage collection

+1

HashMaps не хранит объекты. Они могут хранить ссылки. – immibis

+1

вместо 'HashMap' вы можете использовать' WeakHashMap'. – Prashant

+0

если есть какая-либо устаревшая ссылка на любой объект, который вы удалили с карты, то он не сможет GC. вам нужно сделать это null явно перед удалением. – Prashant

ответ

1

Нет, поскольку у вас может быть ссылка на этот объект из другого места.

Простой пример:

Map < int, Object > map = new HashMap < int, Object >(); 
CustomObject x = new CustomObject(); 
map.put(1, x); 
map.remove(1); 
//you still have access to x 
+0

он означает ... 'map.put (x); x = null; map.remove (x); ' –

+0

@JordiCastilla ' map.remove (x) 'где' x == null' не будет работать должным образом. –

+2

@GoogleHireMe Он означает map.put (ключ, x); х = NULL; map.remove (ключ); – olegst

4

Если вы уверены, что:

нет никаких других ссылок на них

Да, они кандидатов в GC, что не означает, что они будут вовремя вспоминать !!.

Вы можете сделать с:

System.gc(); 

Но это не очень хорошая идея. Для получения дополнительной информации проверьте this и this вопросов.

+0

Привет @olegst, если этот или любой ответ разрешил ваш вопрос, пожалуйста, рассмотрите [его принятие] (http://meta.stackexchange.com/q/5234/179419), нажав галочку. Это указывает более широкому сообществу, что вы нашли решение и дали некоторую репутацию как самому, так и самому себе. Это не обязательно. –

0

Если карта является единственной ссылкой со ссылкой на объект и вы удаляете ссылку на объект с карты, то да, объект больше не ссылается нигде и будет иметь право на GC. Как всегда, ресурсы, которые были получены, гарантированно будут выпущены, но нет гарантии, когда это произойдет.

1

Сбор мусора всегда выполняется в памяти кучи, где все объекты инициализируются. Когда вы вызываете метод remove в HashMap, он удаляет только идентификатор и значение, а не объект, который вы создали.

2

Записи HashMap хранятся в массиве. Если вы удалите запись, позиция соответствующего массива будет null. Таким образом, hashMap больше не ссылается на удаленный объект value.

Тогда нормальные правила сбора мусора будут применяться к объекту value.

Простой код для проверки.

public class REPL7 { 

    public static void main(String[] args) throws Exception { 
     Map<String, Foo> map = new HashMap(); 
     map.put("one", new Foo("foo one")); 
     map.put("two", new Foo("foo two")); 

     // make the backing array accessible 
     Field field = map.getClass().getDeclaredField("table"); 
     field.setAccessible(true); 
     Object[] obj = (Object[]) field.get(map); 

     // two references to Foo objects will be shown    
     System.out.println("obj = " + Arrays.toString(obj)); 

     map.remove("one"); 

     // only one reference to a Foo object will eb shown 
     System.out.println("obj = " + Arrays.toString(obj)); 
    } 
} 

class Foo { 
    String marker; 

    Foo(String marker) { 
     this.marker = marker; 
    } 

    @Override 
    public String toString() { 
     return "Foo{" + marker + '}'; 
    } 
}