0

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

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

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

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

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

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

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

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

4

2 回答 2

0

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

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

请参阅此页面上的弱哈希参考

于 2016-02-07T08:06:17.800 回答
0

我应该在我的方法中使用WeakMapfor吗?WeakReference

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

Map.clear();在现有方法之前调用?

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

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

于 2016-02-07T01:43:56.573 回答