HashMap - это сборка мусора вместе с WeakHashMap? - PullRequest
0 голосов
/ 11 октября 2018

Насколько я понимаю, HashMap не должен собирать мусор, а WeakHashMap должен собирать мусор, но когда я запускаю этот код, и hashmap, и weakhashmap собирают мусор.

import java.util.HashMap;
import java.util.WeakHashMap;
public class WeakHashMapDemo {
    public static void main(String[] args) {
        HashMap<String,Temp> hashMap= new HashMap<>();
        hashMap.put("a", new Temp("hashmap"));
        WeakHashMap<String,Temp> weakHashMap= new WeakHashMap<>();
        weakHashMap.put("a", new Temp("identity hashmap"));
        hashMap= null;
        weakHashMap= null;
        System.gc();
        try {
            Thread.sleep(5000);
        }catch(InterruptedException interruptedException) {
            interruptedException.printStackTrace();
        }
        System.out.println(hashMap);
        System.out.println(weakHashMap);
    }
}
class Temp {
    String name;
    Temp(String name) {
        this.name= name;
    }
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println(name+":: Finalize Method Executed");
    }
    @Override
    public String toString() {
        return this.name;
    }
}

Вывод:

identity hashmap:: Finalize Method Executed
hashmap:: Finalize Method Executed
null
null

При использовании только HashMap сборщик мусора не собирается.

import java.util.HashMap;
import java.util.WeakHashMap;
public class WeakHashMapDemo {
    public static void main(String[] args) {
        HashMap<String,Temp> hashMap= new HashMap<>();
        hashMap.put("a", new Temp("hashmap"));
        System.gc();
        try {
            Thread.sleep(5000);
        }catch(InterruptedException interruptedException) {
            interruptedException.printStackTrace();
        }
        System.out.println(hashMap);
    }
}
class Temp {
    String name;
    Temp(String name) {
        this.name= name;
    }
    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        System.out.println(name+":: Finalize Method Executed");
    }
    @Override
    public String toString() {
        return this.name;
    }
}

Вывод:

{a=hashmap}

Ответы [ 4 ]

0 голосов
/ 11 октября 2018

В строке hashMap= null; вы разыменовали объект HashMap.В любом случае после установки значения null в следующем цикле сборки мусора он будет собираться сборщиком мусора.

Во втором случае вы не устанавливаете hashMap в значение null.

разница между обоимиих:

WeakHashMap - это реализация интерфейса Map.WeakHashMap почти такой же, как HashMap, за исключением случая WeakHashMap, если объект, указанный в качестве ключа, не содержит ссылок - он подходит для сборки мусора, даже если он связан с WeakHashMap.то есть сборщик мусора доминирует над WeakHashMap.

0 голосов
/ 11 октября 2018

Прежде всего, не используйте finalize - это устарело, есть лучшие способы убирать за собой, и ТАК полно таких постов (ReferenceQueue и SoftReferences среди таких).

Тогда не используйте объекты, которые внутренне кэшируются в качестве ключей в WeakHashMap (* String такой).

Последнее замечание: это не имеет ничего общего с WeakHashMap, это базовая живостьобъектов.В первом примере вы явно устанавливаете ссылку на null, таким образом, они очищаются GC, во втором - нет, и сохраняете сильную ссылку на нее через System.out.println(hashMap);;таким образом это не будет собрано.

0 голосов
/ 11 октября 2018

В первом примере для переменной hashMap установлено значение null.Тогда уже нет ссылки на объект HashMap, и его можно собирать мусором, как и любой другой тип объекта.HashMap и WeakHashMap ничем не отличаются в этом отношении.

Разница в том, что ключи в WeakHashMap могут собираться мусором, если на них нет внешних ссылок.В обычном HashMap этого не произойдет, потому что сама карта содержит ссылки на ключи.

Как только ключи собраны, WeakHashMap может очистить всю соответствующую запись. этот ответ более подробно об этом.

0 голосов
/ 11 октября 2018

Я думаю, вы неправильно поняли, как работает GC.

В одном предложении: экземпляры классов собираются как мусор, когда на них больше нет ссылок. Это не имеет ничего общего с типом.

Вот почему так важно обращать внимание на область видимости переменных.Если вы сохраняете ссылку на объект, который вам больше не нужен, он не будет собран, и вы будете тратить ресурсы.

Кроме того, вы вызываете System.gc () ... Вы можете 'Т программно вызвать GC.Он будет работать по своим собственным правилам.В лучшем случае вы можете «предложить» JVM, которую вы хотите запустить GC.

Я бы посоветовал вам взглянуть на: https://www.dynatrace.com/resources/ebooks/javabook/how-garbage-collection-works/

...