【问题标题】:using static dictionary as cache may lead to leak problem?使用静态字典作为缓存可能会导致泄漏问题?
【发布时间】:2010-07-21 13:41:10
【问题描述】:

我正在处理的 Web 应用程序 (servlet) 中存在内存泄漏。我怀疑 1 个原因,想听听您对此的看法。

我使用 hashmaps、hashsets 等作为 DB(加载了大约 20MB 的数据)。这些地图,集合每 10 分钟重新加载一次。有大量的同时请求。我读到,GC 将在一段时间/周期内未收集的对象传递给较少检查或垃圾收集的一代(旧代和永久代)。我认为我对静态地图集的使用导致了我的泄漏问题。你怎么看?

【问题讨论】:

  • 首先感谢您的回答。我会记住你的建议。这里有更多细节;每十分钟我按照以下步骤操作 1) 我在后台创建新地图(作为临时地图)。 2)通过调用 .clear() 方法清除旧地图(甚至在进行步骤 3 之前将它们分配为 null) 3)将新地图的引用提供给旧地图。我可以在这里遗漏什么吗?
  • 访问这些地图的代码元素如何实际访问内容?您确定没有其他代码元素获取对静态 Map 本身的引用吗?将应用程序范围内的数据存储在静态变量中有点代码味道,如果设计不当,很容易导致泄漏问题。

标签: java arrays memory-leaks garbage-collection hashmap


【解决方案1】:

正如 Romain 所指出的,静态地图是可疑的。如果由于某种原因您不能定期明确地清理它,您可以考虑改用WeakHashMap,即

具有弱键的基于哈希表的 Map 实现。 WeakHashMap 中的条目在其键不再常用时将自动删除。更准确地说,给定键的映射的存在不会阻止该键被垃圾收集器丢弃,也就是说,使其可终结,最终确定,然后回收。当一个键被丢弃时,它的条目实际上是从映射中删除的,所以这个类的行为与其他 Map 实现有些不同。

遗憾的是,从 Java6 开始,标准库中似乎没有 WeakHashSet,但网上可以找到几个实现。

【讨论】:

    【解决方案2】:

    如果您删除了对它的所有引用,这不是泄漏。如果您要完全清除地图,则它不是泄漏的来源。您应该考虑 JVM 不经常选择 GC 终身生成这一事实与您无关 - 重要的是您没有对它的引用,因此 JVM 可以 GC 它如果它想要。

    JVM 可以使用不同的策略来管理 GC,所以我在这里泛泛而谈,但 GCingtenured 空间往往非常昂贵并且对应用程序影响很大,所以 JVM 选择不一般来说,经常这样做。

    如果您查看已使用的堆空间量,您会在添加并最终收集项目时看到锯齿模式。不要关心锯齿的顶部在哪里,而要关心底部在哪里(以及与最大可用堆空间量的接近程度)。

    测试是否真的存在泄漏的一种方法是对您的应用进行长时间的负载测试。如果您有泄漏,您的应用程序使用的基本内存量将随着时间的推移而增加(锯齿的底部)。如果你不这样做,它将保持不变。如果确实有泄漏,您可以使用分析器来帮助您找到它。

    【讨论】:

      【解决方案3】:

      静态地图是已知的泄漏源。原因是人们把东西放进去而不是把它们拿走。如果每十分钟您只需清除缓存然后重新加载,那么您应该没问题。

      我敢打赌你没有正确清除它。 GC 部分工作正常,我不会担心这是问题。

      【讨论】:

        【解决方案4】:

        如果您的部分缓存经过 GC,但随后又需要,您可能还需要考虑使用 WeakReference

        【讨论】:

          【解决方案5】:

          我建议您使用堆转储和堆分析器(例如JVisualVM)检查堆内容。这将帮助您找到泄漏的嫌疑人。老年代被收集的频率较低并不意味着更多的内存泄漏。请记住,虽然它可能看起来已满,但其中只有一部分表示活动对象,而另一部分则由下一次主要 GC 清除。正如其他人所说,问题可能是由于对静态集合的清理不完整。

          永久代永远不会收到提升的对象。它是为其他目的保留的堆外区域,例如加载的类的反射信息和内部字符串。

          【讨论】:

            猜你喜欢
            • 2013-07-26
            • 1970-01-01
            • 2011-02-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-08-16
            相关资源
            最近更新 更多