3

我有缓存,用 Wea​​kHashMap 实现,如下所示:

private static WeakHashMap<Object, WeakReference<Object>> objects = new WeakHashMap<>();

我有一个 City 类的实例:

City c = new City();

我现在将此实例添加到我的地图中,如下所示:

objects.put(c, new WeakReference<Object>(c));

根据 WeakHashMap jvm 实现,如果 key 没有对其的强引用,则将其从地图中删除(在其空闲时间)。
因此,如果程序中不再使用我的对象“c”,它将从“对象”映射中删除。
到目前为止,一切都很好。

但是如果我有两张地图会怎样?

private static WeakHashMap<Object, WeakReference<Object>> objects1 = new WeakHashMap<>();
private static WeakHashMap<Object, WeakReference<Object>> objects2 = new WeakHashMap<>();
City c = new City();
objects1.put(c, new WeakReference<Object>(c));
objects2.put(c, new WeakReference<Object>(c));

在这种情况下,GC 会收集对象“c”吗?

4

3 回答 3

3

拿一张纸,以对象为顶点,以引用为边绘制图形。

如果您找不到从 GC 根(例如堆栈上的静态字段或局部变量)到所讨论对象的强边缘路径,则它不是强可达的,因此符合 GC 条件。

于 2016-07-07T15:37:09.967 回答
1

当然,它会收集它(当 GC 开始时),因为它仍然由 WeakReference 引用而不是 Strong 引用,无论有多少 WeakReference 引用它。

您可以在此处阅读有关 WeakReference 的信息:WeakReference

这是一个示例来演示它:

public class WeakHashMapExample {

  //strongly reference key to prevent GC from collecting it
  private static final Key stronglyRefKey1 = new Key(1);

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

    WeakHashMap<Key, String> cache1 = new WeakHashMap<>();
    WeakHashMap<Key, String> cache2 = new WeakHashMap<>();

    //adding same keys
    Key key2 = new Key(2);
    cache1.put(stronglyRefKey1, "val 1");
    cache1.put(key2, "val 2");
    cache2.put(stronglyRefKey1, "val 1");
    cache2.put(key2, "val 2");
    key2 = null; // remove strong reference

    //may or may not print Key(2) key, depends if GC starts at this point
    System.out.println("cache1 = " + cache1);
    System.out.println("cache2 = " + cache2);

    //for GC to start so all weak reference should be cleared
    System.gc();

    //after GC ha been ran, key(2) will be removed because its only referenced by weak reference of the WeakHashMap
    System.out.println("cache1 = " + cache1);
    System.out.println("cache2 = " + cache2);
  }

  private static class Key{
    int value;

    private Key(int value) {
      this.value = value;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;

      Key key = (Key) o;

      if (value != key.value) return false;

      return true;
    }

    @Override
    public int hashCode() {
      return value;
    }

    @Override
    public String toString() {
      return "Key{value=" + value +'}';
    }
  }
}
于 2016-07-07T16:40:48.707 回答
0

弱就是弱,再加上一个弱,它就不会变强。

如果没有其他强引用,它将被垃圾收集。毫无疑问。

于 2016-07-07T16:13:20.653 回答