如何防止Eclipselink使用缓存消耗所有内存?

时间:2012-12-17 13:13:37

标签: java memory-leaks persistence eclipselink

我的应用程序提取了大量的几何数据。我使用Eclipselink 2.4.1将数据保存在MySQL数据库中。该应用程序以批处理方式工作,即我收集一组数据,然后保留它,继续下一组,保持它等等。另一个应用程序稍后会读取该数据并对其进行处理,但这个问题仅涉及收集数据的第一个应用程序。

数据收集应用程序运行了一段时间。我使用一组固定的EntityManagers,它们是在启动时创建的,直到应用程序完成为止。提取是多线程的,每个线程有一个EntityManager。我的问题是,无论我如何配置缓存,一段时间后EclipseLink会占用所有内存,过了一段时间我得到了OutOfMemoryError

我使用VisualVM来提取我使用Eclipse Memory Analyzer分析的堆转储。 EntityManagerImpl.extendedPersistenceContext.cloneMapping持有可疑数量的记忆。此映射包含对我的几何数据对象的引用。随着时间的推移,这个地图的大小会达到数百兆,这就是造成内存不足的原因。

我已经尝试了以下内容:

  • 我通过配置eclipselink.persistence-context.reference-mode=weak来使用弱引用。我已确认EntityManagerImpl.extendedPersistenceContext.cloneMapping属于IdentityWeakHashMap类型。从documentation about weak caches开始,我希望使用参考模式weak解决问题。不幸的是,垃圾收集器仍然没有声明条目,我不断出现内存错误。
  • 我尝试使用eclipselink.cache.shared.default=false完全关闭缓存。问题依然存在。

有没有人建议这里发生了什么以及如何解决这个问题?我也愿意接受如何规避问题的建议。

1 个答案:

答案 0 :(得分:2)

一些事情。

首先,你不应该保持长期存在的EntityManagers。您应该为每个事务或每个请求创建一个新的EntityManger。

其次,确保你的应用程序(静态变量等)没有持有对象的引用,如果有什么东西引用了它不会被垃圾收集的对象。