Java 在weakHashMap中,如果我更新或更改以前存储的密钥对象,垃圾收集器将删除该密钥-值对

Java 在weakHashMap中,如果我更新或更改以前存储的密钥对象,垃圾收集器将删除该密钥-值对,java,garbage-collection,weakhashmap,Java,Garbage Collection,Weakhashmap,我在WeakHashMap中存储了一个对象作为密钥。现在,如果我更改它的值,然后调用GC并打印map,那么就什么都没有了 public static void main(String[] args) throws InterruptedException{ WeakHashMap map = new WeakHashMap(); Integer obj = new Integer(200); map.put(obj, "sgdjsgd"); obj=new In

我在
WeakHashMap
中存储了一个对象作为密钥。现在,如果我更改它的值,然后调用GC并打印
map
,那么就什么都没有了

public static void main(String[] args) throws InterruptedException{

    WeakHashMap map = new WeakHashMap();
    Integer obj = new Integer(200);
    map.put(obj, "sgdjsgd");
    obj=new Integer(20);
    System.gc();
    Thread.sleep(2000);
    System.out.println(map);
}
  • 预期输出:
    {200,“sgdjsgd”}
  • atual输出:
    {}

    • 使用此代码,您可以更改存储在
      obj
      中的内存指针:

      obj=new Integer(20);
      
      在这一行之前,
      obj
      持有指向
      新整数(200)的指针引用

      现在,相反,
      obj
      持有指向新整数(20)的指针引用与内存中的上一个不同


      因此,因为
      WeakHashMap
      持有弱引用,所以当垃圾收集器运行时,它会收集映射引用的对象,因此当您打印映射时,它会显示
      {}
      因为保存在地图键中的指针已找不到了。

      使用此代码,您可以更改存储在
      obj
      中的内存中的指针:

      obj=new Integer(20);
      
      在这一行之前,
      obj
      持有指向
      新整数(200)的指针引用

      现在,相反,
      obj
      持有指向新整数(20)的指针引用与内存中的上一个不同


      因此,因为
      WeakHashMap
      持有弱引用,所以当垃圾收集器运行时,它会收集映射引用的对象,因此当您打印映射时,它会显示
      {}
      因为保存在地图键中的指针找不到了。

      我不确定您想做什么,但我在您的代码中看到的是,您将一个新对象分配给一个引用,该引用先前指向WeakHashMap中的键,通过这样做,原始键(整数(200))没有指针,因此它是无用的,因为您永远无法到达该键,因此gc将处理它是合乎逻辑的,我不确定您要做什么,但我在代码中看到的是,您将一个新对象分配给一个引用,该引用先前指向WeakHashMap中的键,通过这样做,原始键(整数(200))没有指针,因此它是无用的,因为您永远无法访问该键,因此gc将处理它是合乎逻辑的

      WeakHashMap可能会表现为未知线程正在静默删除条目

      WeakHashMap.Entry
      是一个
      WeakReference
      对象,其引用对象是传递给
      map.put()
      对象。也就是说,如果
      变为
      弱可访问
      ,垃圾收集器将自动声明它可终结

      Java SE 8文档说:

      如果对象既不是强可及对象,也不是软可及对象,但可以通过遍历弱引用来达到该对象,则该对象是弱可及对象。当清除对弱可达对象的弱引用时,该对象就有资格进行终结

      在这行代码中

      Integer obj=新整数(200);
      地图放置(obj,“sgdjsgd”);
      
      obj
      是对由
      newinteger(200)
      创建的整数对象的强引用,然后它被传递到
      map.put()
      ,后者创建一个
      WeakReference
      (假设它被称为
      w
      )来保存这个整数对象

      但在这一行之后:

      obj=新整数(20);
      
      obj
      指向另一个容纳20的整数对象(
      w
      仍然指向容纳200的整数对象)。 但是,更改
      obj
      指向的对象将使
      w
      的参照物成为
      弱可及的
      ,因为它只能通过遍历弱参照(即
      w
      )来达到

      当控件从对
      System.gc()
      的方法调用返回时,JVM已尽最大努力回收所有丢弃的对象。如上所述,垃圾收集器将以原子方式声明弱可达对象可终结,并最终清除它们


      因此,
      w
      被清除,垃圾收集器将丢弃映射中的条目,因此,您的映射不包含任何内容。

      WeakHashMap的行为可能就好像一个未知线程正在默默地删除条目一样

      WeakHashMap.Entry
      是一个
      WeakReference
      对象,其引用对象是传递给
      map.put()
      对象。也就是说,如果
      变为
      弱可访问
      ,垃圾收集器将自动声明它可终结

      Java SE 8文档说:

      如果对象既不是强可及对象,也不是软可及对象,但可以通过遍历弱引用来达到该对象,则该对象是弱可及对象。当清除对弱可达对象的弱引用时,该对象就有资格进行终结

      在这行代码中

      Integer obj=新整数(200);
      地图放置(obj,“sgdjsgd”);
      
      obj
      是对由
      newinteger(200)
      创建的整数对象的强引用,然后它被传递到
      map.put()
      ,后者创建一个
      WeakReference
      (假设它被称为
      w
      )来保存这个整数对象

      但在这一行之后:

      obj=新整数(20);
      
      obj
      指向另一个容纳20的整数对象(
      w
      仍然指向容纳200的整数对象)。 但是,更改
      obj
      指向的对象将使
      w
      的参照物成为
      弱可及的
      ,因为它只能通过遍历弱参照(即
      w
      )来达到

      当控件从对
      System.gc()
      的方法调用返回时,JVM已尽最大努力回收所有丢弃的对象。如上所述,垃圾收集器将以原子方式声明弱可达对象可终结,并最终终止
      Integer obj = new Integer(200);
      
      map.put(obj, "sgdjsgd");
      
      obj=new Integer(20);