问题:
我有一个应用程序,从几年开始,我通常定期处理6万至6m个点。
现在我的测量值约为4300万点。 试图更改单个点的状态最终会导致内存不足的异常。
处理过程将进行3次测量(每个〜60k点),并在第4次非常大的测量中分解:save()方法一直运行直到我收到OOM。
堆栈
Sprint引导1.5.16.Hibernate和Postgres 9.5的发布。
简化代码
// pageSize worked with 300k before but for debugging: 500
Page<Point> page = getNextPage(m, pageSize);
ResultCache result = process(page);
// This is the cause of the OOM, even with a single point!
repo.save(result.getChangedPoints());
// save(one single element) also ends up in the OOM so I cannot execut code afterwards like flush
private Page<Point> getNextPage(Measurement m, int pageSize) {
return repo.findByMeasurement(m, new PageRequest(0, pageSize));
}
@Repository
public interface PointRepository extends
JpaRepository<Point, Long> {}
调试
当我在IDE中调试时,我到达第一个repo.save()
语句,但是一旦执行该语句,内存就会自动填满,直到达到〜4 GB,几分钟后我收到一个OOME。
问题
如何避免OOM?为什么Page的总元素数如此重要?我以为只有页面大小会影响加载到内存中的数据量。
分析
更新
当我重置点的状态(已处理=否)时,处理将再次进行直到测量4,然后我看到相同的行为。
我可以在数据库中手动更新点,没有问题。