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

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

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

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

我已经尝试过以下方法:

  • 我通过配置eclipselink.persistence-context.reference-mode=weak使用弱引用。 我已经validation了EntityManagerImpl.extendedPersistenceContext.cloneMapping的类型是IdentityWeakHashMap 。 从关于弱缓存的文档中我可以预期,使用weak模式可以解决问题。 不幸的是,垃圾收集器仍然没有声明条目,我不断出现内存错误。
  • 我试图用eclipselink.cache.shared.default=false完全关闭缓存。 问题依然存在。

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

一些东西。

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

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