带有Pagable(小页面,但元素总数很多)的repo.save()上的内存不足

时间:2018-09-27 08:23:10

标签: hibernate spring-boot spring-data-jpa out-of-memory postgresql-9.5

问题:

我有一个应用程序,从几年开始,我通常定期处理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的总元素数如此重要?我以为只有页面大小会影响加载到内存中的数据量。

分析

Memory snapshot

更新

  • 当我重置点的状态(已处理=否)时,处理将再次进行直到测量4,然后我看到相同的行为。

  • 我可以在数据库中手动更新点,没有问题。

0 个答案:

没有答案