有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何防止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) 个答案

  1. # 1 楼答案

    有几件事

    首先,你不应该让实体经理长寿。您应该为每个事务或每个请求创建一个新的EntityManger

    第二,确保应用程序(静态变量等)没有保存对对象的引用,如果有任何对象引用了它不会进行垃圾收集的对象