代码之家  ›  专栏  ›  技术社区  ›  Shubhamhackz

HashMap和WeakHashMap一起被垃圾收集?

  •  2
  • Shubhamhackz  · 技术社区  · 7 年前

    据我所知,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
    

    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 回复  |  直到 7 年前
        1
  •  3
  •   Eugene    7 年前

    finalize ReferenceQueue SoftReferences 是其中之一)。

    然后不要使用内部缓存的对象作为中的键 WeakHashMap String

    最后一点是,这与 懦夫地图 明确地 将引用设置为 null ,因此它们被GC清除,在你的第二个GC中你不清除,并通过 System.out.println(hashMap); ; 因此它不会被收集。

        2
  •  3
  •   OhleC    7 年前

    在第一个示例中,设置 hashMap null . 这样就不再引用HashMap对象了,它可以像任何其他类型的对象一样被垃圾收集。 HashMap WeakHashMap 在这方面没有什么不同。

    不同的是 钥匙 懦夫地图 在没有外部引用时可能会被垃圾收集。正常情况下 哈希图 ,这不会发生,因为映射本身包含对键的引用。

    一旦钥匙被收集起来 可以清除整个相应的条目。 this answer 更详细地说。

        3
  •  1
  •   Diego    7 年前

    我想你误解了GC的工作原理。

    一句话:类的实例在不再被引用时被垃圾收集。 它与类型无关。

    这就是为什么关注变量的范围如此重要。如果你保留了一个你不再需要的对象的引用,它将不会被收集,你将浪费资源。

    我建议你看看: https://www.dynatrace.com/resources/ebooks/javabook/how-garbage-collection-works/

        4
  •  1
  •   Khalid Shah    7 年前

    At线 hashMap= null; 您取消了对HashMap对象的引用。在任何情况下,在设置null之后,在垃圾回收的下一个循环中,它将由垃圾回收器收集。

    两者的区别:

    WeakHashMap是Map接口的一个实现。WeakHashMap与HashMap几乎相同,只是在WeakHashMap的情况下,如果将对象指定为键,则该对象不包含任何引用—即使它与WeakHashMap关联,它也有资格进行垃圾回收。i、 垃圾收集器在WeakHashMap上占主导地位。