【问题标题】:use WeakHashMap in a method or not?是否在方法中使用 Wea​​kHashMap?
【发布时间】:2016-02-07 01:32:02
【问题描述】:

我有一个每 5 分钟调用一次的 @Scheduled 方法。

批处理进行大量计算,大约需要 2-15 分钟才能完成(如果批处理已经在运行,有一个标志会阻止批处理运行)。

我使用大量Maps 来缓存计算结果。我可以这样恢复。一个主要的 Map 将包含累积结果,以及一些 Map/List into submethod for internal calculus。

批处理可能需要大约 3-6 Gigs 才能运行。要分析大量数据。

我认为当代码退出方法时,我在方法中使用的 Map/List 将有资格进行 GC,对吧?

我应该在我的方法中使用WeakHashMapWeakReference 还是在退出方法之前调用Map.clear();

如果可能,我想减少内存使用量,不要在批处理结束时等待 GC 进行清理。

批处理完成后,内存将减少到 500megs-1G max。

【问题讨论】:

  • 我想你不想在你的方法还在运行的时候丢失缓存的值,所以弱引用/映射并不是很有用。此外,它会导致相反的结果,在方法运行时收集部分数据会提高 CPU 使用率。最后一次释放所有数据不会产生任何成本,垃圾收集器的资源消耗与剩余对象成正比,而不是与死对象成正比。

标签: java garbage-collection spring-batch weak-references weakhashmap


【解决方案1】:

我应该在我的方法中使用WeakMap 代替WeakReference 吗?

仅当您保留对数据的其他引用并且您不想阻止该数据被垃圾收集时,弱引用才有效。看起来这不是您正在做的事情,因为您需要这些数据才能继续处理。

或者在方法存在之前调用Map.clear();

如果映射是您的方法的本地映射,则调用 clear() 不会以任何有意义的方式加速 GC。但是,如果您的映射是在您的方法退出后仍然可用的对象上的字段,那么调用 clear 是避免“持续内存泄漏”的重要方法。

就减少内存占用而言,诀窍是确定不再需要的数据子集,并尽早释放它。如果您一直需要所有数据,或者如果您无法确定接下来需要哪些数据,您将无法减少程序的临时占用空间。

【讨论】:

    【解决方案2】:

    我感觉你想使用 Wea​​kHashMap。 WeakHashMap 使用弱引用来保存映射键,这允许在应用程序不再使用键对象时对其进行垃圾回收,并且 get() 实现可以通过是否 WeakReference.get() 来区分活动映射和死映射返回空值。但这只是在应用程序的整个生命周期中保持 Map 的内存消耗不增加所需的一半;在收集到关键对象后,还必须做一些事情来从 Map 中删除死条目。否则,Map 将简单地填充与死键对应的条目。虽然这对应用程序是不可见的,但它仍然可能导致应用程序耗尽内存,因为不会收集 Map.Entry 和 value 对象,即使键是。

    可以通过定期扫描 Map、在每个弱引用上调用 get() 并在 get() 返回 null 时删除映射来消除死映射。但是,如果 Map 有许多实时条目,这将是低效的。如果有一种方法可以在弱引用的所指对象被垃圾回收时得到通知,那就太好了,这就是引用队列的用途。

    请参阅此页面Weak Hash Reference

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多