【问题标题】:static HashMap is causing the memory leak,but how to rectify it?static HashMap 导致内存泄漏,但如何纠正呢?
【发布时间】:2012-12-21 23:59:12
【问题描述】:

private static Map<interface,class> m =new HashMap<interface,class>;

是一个类的实例变量。

class Synchronized(m){m.put(this,this);}的构造函数中,

这里的问题是键和值是相同的,因此当更新的指示即将到来时,H​​AshMap 正在收集所有数据并且它从未被 GC'ed。它导致泄漏。

我尝试了解决方法并删除了 static 关键字,它工作正常。但我认为删除 static 会导致一些严重的问题。

有没有其他方法可以纠正这种泄漏。代码重构是不可能的,因为它真的很复杂,而且我的时间不多了。任何人请指导我。提前致谢

【问题讨论】:

  • "m 是一个类的实例变量。" => 不,它是一个静态(或类)变量。使地图静态与否完全没有相同的含义。你需要/想要哪个?为什么?
  • 为什么哈希映射中的键和值是相同的?为什么不直接使用HashSet
  • 你能显示你的接口类的代码......你用它作为键吗?
  • @DougRamsey 实际上我不知道他们为什么需要这样。但是现在我必须以任何方式纠正它以解决内存泄漏。您是否建议使用 HashSet 而不是 HashMap?是否需要进行更多更改?
  • 好吧,Java 不会“泄漏内存”,所以如果对象没有在压力下释放,那么有人 - 例如HashMap,但可能是另一个集合 - 保持对象强可达。虽然有各种“弱引用”HashMap 等,但它可能只是一个设计问题,即在某些时候(即当它们不再相关/不再使用时)没有正确删除对象。

标签: java memory-management memory-leaks static jvm


【解决方案1】:

如果 Hashmap 条目对象(条目对象存储键值对)不符合垃圾回收条件。也就是说,即使与键值对关联的键对象为空,条目对象也会保留在内存中。

而在weakhashmap的情况下,WeakHashMap中的一个条目将在其键不再正常使用时自动被删除(即使对给定键进行映射也不会阻止该键被生成的垃圾收集器丢弃finalizable , finalized 然后回收)。当一个键被丢弃时,它的条目会自动从映射中删除,换句话说,就是垃圾回收。

WeakHashMap 中的每个键对象都间接存储为弱引用(也称为硬引用)的引用。因此,只有在对它的弱引用之后,一个键才会被自动删除,无论是在映射内部还是外部,已被垃圾收集器清除。 例子: public static void main(String[] args) {

    Map<String, String> map = new HashMap<String, String>();
    Map<String, String> map2 = new WeakHashMap<String, String>();
    String hashmapKey = new String("hashmapkey");
    String weakhashmapKey = new String("weakhashmapkey");

    map.put(hashmapKey, "value");
    map2.put(weakhashmapKey, "value");
    System.out.println("Before garbage call");
    System.out.println(map);
    System.out.println(map2);

    hashmapKey = null;
    weakhashmapKey = null;

    System.out.println("After garbage call");
    System.gc();
    System.out.println(map);
    System.out.println(map2);

}

输出:

垃圾调用之前 {hashmapkey=值} {weakhashmapkey=值} 垃圾电话后 {hashmapkey=值} {}

【讨论】:

    【解决方案2】:

    如果它适合您的用例,请参考 WeakHashMap

    【讨论】:

      【解决方案3】:

      如果哈希映射保留了您不想要的条目,那是因为您没有删除它们。

      如果您只保留所需的条目,则静态集合没有特别的原因会导致内存泄漏。

      【讨论】:

      • @Peter Lawrey 所以在这种情况下,如果我使用 removeAllEntries(this,this);就在 m.put(this,this); 下方它会起作用吗?
      • 如果你正确使用m.remove(this);m.remove(toBeRemoved);,你就不会有你不想要的对象。
      • 先生,实际上客户端正在定期获取更新的指示。这里的问题是,如果更新的指示来了,那么就没有使用 ealier 的指示。所以我尝试了 ypu 建议的 m.remove(this);并检查内存利用率。非常感谢。
      • 内存利用率很好但是客户端现在没有问题创建类指示?我很困惑,如果这段代码可以很好地处理每个指示,那么为什么一个特定的类会产生问题以及我何时使用 m.remove(这);那么它甚至没有出现在客户面前?请帮帮我....谢谢
      • 我不明白你的意思。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-08
      • 2015-07-06
      • 2014-06-07
      • 2013-11-20
      • 2011-10-28
      相关资源
      最近更新 更多