我的应用程序提取了大量的几何数据。我使用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
完全关闭缓存。问题依然存在。有没有人建议这里发生了什么以及如何解决这个问题?我也愿意接受如何规避问题的建议。
答案 0 :(得分:2)
一些事情。
首先,你不应该保持长期存在的EntityManagers。您应该为每个事务或每个请求创建一个新的EntityManger。
其次,确保你的应用程序(静态变量等)没有持有对象的引用,如果有什么东西引用了它不会被垃圾收集的对象。