java - 带有字符串文字和字符串对象的 weakhashmap 的行为

标签 java weakhashmap

我正在理解 WeakhashMap 的概念。字符串文字和字符串对象让人难以理解。

代码如下:

package com.lnt.StringBuf;

import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;

public class Test1 {
    public static void main(String[] args) {

        Map w = new WeakHashMap();
        Map h = new HashMap<>();

        String hkey = new String("hashkey");
        String wkey = new String("weakkey");
    /*  String hkey = "hashkey";
        String wkey = "weakkey";*/

        h.put(hkey, 1);
        w.put(wkey, 1);

        System.gc();

        System.out.println("Before");
        System.out.println("hashmap size: " + h.size());
        System.out.println("weakmap size: " + w.size());
        System.out.println("Hashmap value: " + h.get("hashkey") + "\t"
                + "weakmap value: " + w.get("weakkey"));

        hkey = null;
        wkey = null;

        System.gc();
        System.out.println(hkey+" "+wkey);

        System.out.println("After");
        System.out.println("hashmap size: " + h.size());
        System.out.println("weakmap size: " + w.size());
        System.out.println("Hashmap value: " + h.get("hashkey") + "\t"
                + "weakmap value: " + w.get("weakkey"));

        System.out.println(h.entrySet());
        System.out.println(w.entrySet());

    }

}

输出是:

Before
hashmap size: 1
weakmap size: 1
Hashmap value: 1    weakmap value: 1
null null
After
hashmap size: 1
weakmap size: 0
Hashmap value: 1    weakmap value: null
[hashkey=1]
[]

但是当 String hkey = new String("hashkey"); String wkey = new String("弱键");

替换为以下代码,输出更改。

String hkey = "hashkey";
String wkey = "weakkey";

输出是:

Before
hashmap size: 1
weakmap size: 1
Hashmap value: 1    weakmap value: 1
null null
After
hashmap size: 1
weakmap size: 1
Hashmap value: 1    weakmap value: 1
[hashkey=1]
[weakkey=1]

问题:在 WeakHashMap 中使字符串字面值和字符串对象为“空”的影响方式不同。这是什么原因?

最佳答案

字符串文字是驻留的,这基本上意味着有一个缓存,通常称为字符串池。所以字符串文字总是被强引用——这使得它们不适合用作弱结构中的键,例如WeakReferenceWeakHashMap

自动装箱的 int 也是如此:Integer 也为 int 值保留 Integer 对象的缓存在 [-128, 127] 范围内。因此,您也不应该将 int 用于弱结构中的键。

但是,您可以通过在插入条目时创建一个新对象来解决这些问题,例如在下面的示例中,“a”条目最终将从映射中删除,但“b”条目将永远保留在那里,这实际上是内存泄漏:

WeakHashMap<String, Object> map = new WeakHashMap<>();
map.add(new String("a"), new Object());
map.add("b", new Object());

同样的例子也适用于整数:

WeakHashMap<Integer, Object> map = new WeakHashMap<>();
map.add(new Integer(56), new Object());
map.add(57, new Object());

由于 Integer 的缓存,57 的条目将永远保留在那里,但垃圾收集器可以删除 56 的条目。

Boolean 也有缓存,但当然只有 2 个值。 Integer 有 256 个潜在的危险值,而 String 实际上有无限次的危险——你只需要使用文字(或使用 String.intern()) 来创建它们。可能还存在其他危险类。

关于java - 带有字符串文字和字符串对象的 weakhashmap 的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23881219/

相关文章:

java - WeakHashMap 与 HashMap

具有不可变键的 Java WeakHashMap

java - 为什么 WeakHashMap 在 GC 后对值有强引用?

java - 什么是 WeakHashMap 以及何时使用它?

java - coursera java 类(class)中方法 getAverageRank 的问题

java - Spring HATEOAS 1.0,删除了 BaseUriLinkBuilder

java - 字符串排序和字符串比较有什么区别。它们不是和我们必须比较字符串才能对其进行排序一样吗?

java - 如何找到特定字符串在图像上的位置?

java - 将浮点值分配给 double 值

Java WeakHashMap 引用未更新