2

我的应用程序提取大量几何数据。我使用 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。从有关弱缓存的文档中,我希望使用参考模式weak可以解决问题。不幸的是,垃圾收集器仍然没有认领这些条目,而且我不断出现内存不足的错误。
  • 我试图用eclipselink.cache.shared.default=false. 问题仍然存在。

有人对这里发生的事情以及我如何解决这个问题有任何建议吗?我也愿意就如何规避这个问题提出建议。

4

1 回答 1

2

一些东西。

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

其次,确保您的应用程序(静态变量等)没有持有对对象的引用,如果有任何东西正在引用该对象,它将不会进行垃圾收集。

于 2012-12-17T15:06:57.573 回答