Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 弱hashmap是否会在其被取消引用后立即释放内存?_Java_Hashmap - Fatal编程技术网

Java 弱hashmap是否会在其被取消引用后立即释放内存?

Java 弱hashmap是否会在其被取消引用后立即释放内存?,java,hashmap,Java,Hashmap,下面是将一些值放入WeakHashMap,然后从映射中删除这些值的代码片段。它如何处理分配的内存 import java.util.*; public class WeakHashMap_Main { private static Map map; public static void main(String args[]) { map = new WeakHashMap(); map.put(new String("ABC"), "XYZ");

下面是将一些值放入WeakHashMap,然后从映射中删除这些值的代码片段。它如何处理分配的内存

import java.util.*;
public class WeakHashMap_Main {
    private static Map map;

    public static void main(String args[]) {
        map = new WeakHashMap();
        map.put(new String("ABC"), "XYZ");
        map.put(new String("DEF"), "PQR");

        map.remove("ABC");
        map.remove("DEF");
    }
}

内存在对象创建时分配给对象。任何数量的其他对象都可能引用该对象,从而引用其分配的内存

垃圾收集器是JVM的一个元素,它确定哪些对象仍然被引用(以及哪些对象是弱引用的)。它将不再引用的所有内存放回堆中,并准备再次使用。在任何情况下,如果内存足够低,等等,它也会将仅由弱引用引用的内存放回堆中,并对弱引用施展魔法,以便程序可以判断它们不再有效


因此,如果您将对对象的引用放在WeakHashMap中,然后将其取出,而这些是对这些对象的唯一引用,那么这些对象将不再被引用,并可用于垃圾收集。

WeakHashMap
使用
键的
WeakReferences
。正常的
HashMap
使用键的
strong引用


垃圾收集由JVM自行管理。我们只能通过调用
System.gc()
来影响JVM执行垃圾收集
HashMap
防止密钥被垃圾收集
WeakHashMap
不会阻止密钥被垃圾收集。如果存储在普通
HashMap
中的密钥没有
strong引用
,它将一直存储在
HashMap
中,直到它被明确删除,之后密钥对象将有资格进行垃圾收集。但是,如果没有任何
strong引用的密钥存储在
WeakHashMap
中,它将有资格进行垃圾收集。一旦执行垃圾收集循环,密钥将被垃圾收集,然后该密钥对象上的
contains
方法将返回
false

在如下情况下,可释放
WeakHashMap
使用的内存:

public static void main(String args[]) {
    Map<String, String> map = new WeakHashMap<>();
    String abc = "ABC";
    String def = "DEF";
    map.put(abc, "XYZ");
    map.put(def, "PQR");
    System.out.println(map.size());  // Guaranteed to be 2.

    // Note: DO NOT remove the map entries!
    // map.remove("ABC");
    // map.remove("DEF");

    // Allow the objects to be reclaimed
    abc = null;
    def = null;

    // Do loads of memory-hungry operations here...
    ...

    System.out.println(map.size());  // MAY POSSIBLY be 0 or 1. Or still 2.
}
publicstaticvoidmain(字符串参数[]){
Map Map=newweakhashmap();
字符串abc=“abc”;
字符串def=“def”;
地图放置(abc,“XYZ”);
地图放置(def,“PQR”);
System.out.println(map.size());//保证为2。
//注意:不要删除地图条目!
//地图。删除(“ABC”);
//地图。删除(“DEF”);
//允许回收对象
abc=null;
def=null;
//在这里执行大量内存不足的操作。。。
...
System.out.println(map.size());//可能是0或1,或者仍然是2。
}
这完全取决于垃圾收集器决定做什么(如果有的话)

这里的要点是,在添加两个条目之后,我们还没有触及地图。

Java文档(jdk1.8.0_71)说

WeakHashMap
中的条目如果是键,将自动删除 已不再是普通用途。更准确地说,存在一个 给定密钥的映射不会阻止密钥被丢弃 通过垃圾收集器

这清楚地表明,当
被丢弃时,其
条目
也将从
映射
中删除

现在,让我们看看发动机罩下面,看看当
键被拔下时会发生什么。
remove(Object o)
方法的代码片段如下所示:

public V remove(Object key) {
        Object k = maskNull(key);
        int h = hash(k);
        Entry<K,V>[] tab = getTable();
        int i = indexFor(h, tab.length);
        Entry<K,V> prev = tab[i];
        Entry<K,V> e = prev;

        while (e != null) {
            Entry<K,V> next = e.next;
            if (h == e.hash && eq(k, e.get())) {
                modCount++;
                size--;
                if (prev == e)
                    tab[i] = next;
                else
                    prev.next = next;
                return e.value;
            }
            prev = e;
            e = next;
        }

        return null;
    }
Entry<K,V> e = tab[i];
tab[i] = new Entry<>(k, value, queue, h, e);
从代码片段可以看出,添加到
WeakHashMap
的每个条目都将该条目存储在此
队列中(在
put(K,V)
操作期间调用构造函数如下所示:

public V remove(Object key) {
        Object k = maskNull(key);
        int h = hash(k);
        Entry<K,V>[] tab = getTable();
        int i = indexFor(h, tab.length);
        Entry<K,V> prev = tab[i];
        Entry<K,V> e = prev;

        while (e != null) {
            Entry<K,V> next = e.next;
            if (h == e.hash && eq(k, e.get())) {
                modCount++;
                size--;
                if (prev == e)
                    tab[i] = next;
                else
                    prev.next = next;
                return e.value;
            }
            prev = e;
            e = next;
        }

        return null;
    }
Entry<K,V> e = tab[i];
tab[i] = new Entry<>(k, value, queue, h, e);
条目e=tab[i];
tab[i]=新条目(k,值,队列,h,e);

)在删除操作期间,将从
队列
中检索并删除相同的条目。此删除的
条目的值设置为null
e.value=null
,稍后将GC'd。是的,它对GC没有任何控制权。这就是
WeakHashMap
如何帮助丢弃带有键的映射值。

释放内存是由垃圾收集器在必要时完成的。无法保证在任何特定时间释放内存;这取决于垃圾收集器的实现。通常,你不需要如此有力的保证。让GC完成它的工作,不用担心。现在大家都知道GC的功能了。我想知道一周散列图的特色。谢谢你的详细解释。。谁称之为expungeStaleEntries()?这是否像WeakHashMap上的任何操作都会调用此函数一样?我很高兴它对您的学习有所帮助
expungestalentries()
WeakHashMap
中的私有方法。它由
private Entry[]getTable()
方法调用,就像我在前面的解释中提到的那样。每当在映射上调用
remove(Object o)
方法时,
remove()
方法依次调用此
getTable()
,以获取有效的数组
条目
。是否有理由不删除映射条目?我知道将键设为null是可行的,但我认为从WaelHashMap中删除kay值也有同样的效果。对吗?如果你想的话,你可以删除映射条目,但是如果你要这样做,你最好使用一个普通的HashMap。我的代码示例显示了WeakHashMap和HashMap之间的区别。非常感谢:)