0

我们有一个使用 Data Nucleus 1.1.4 / JDO 2.3 进行持久性的 Java Web 应用程序。

有一个批量导入操作可以一次性保存大量 JDO 对象。由于要导入的数据太大,我们遇到了一些抛出 OutOfMemoryError 的情况。

预期的模式是循环输入流,解析一行,实例化一个 JDO 对象,调用 makePersistent,然后释放对 JDO 对象的对象引用,以保持我们的内存占用平坦,而不管输入数据大小如何。

在此操作期间对堆进行一些分析时,JDO 对象实例似乎堆积起来并占用了大量内存,直到发生这种commit情况。尽管我们没有引用它们,但它看起来像 Data NucleusPersistenceManagerTransactionimplementations 引用org.datanucleus.ObjectManagerImpl持有“脏”JDO 对象实例(实际上是原始副本)列表的对象。这可能有一个很好的理由,但我有点惊讶框架需要保存每个 JDO 对象的副本。它们在提交后被释放,但鉴于我们要确保所有插入原子地发生,我们需要在事务内部运行此操作。在当前状态下,内存使用与数据输入大小呈线性相关,这为这些 OutOfMemoryErrors 敞开了大门——如果不是针对单个操作,那么在并发操作下。

对于像这样的批处理 JDO 插入操作,是否有任何关于保持接近平坦内存占用的提示或最佳实践?

4

1 回答 1

0

我发现最好的做法是通过循环定期调用 PersistenceManager 的刷新方法。这会导致 JDO 框架 (ObjectManagerImpl) 释放对象。

于 2013-06-03T16:28:11.417 回答