减少批处理JDO插入的内存使用量

时间:2013-05-23 23:09:22

标签: java jdo datanucleus

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

批处理导入操作一次性保留大量JDO对象。我们遇到了一些抛出OutOfMemoryError的情况,因为要导入的数据太大了。

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

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

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

1 个答案:

答案 0 :(得分:0)

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