Проблема:
У меня есть приложение, в котором я обрабатываю измерения обычно с точками 60k-6m на регулярной основе уже пару лет.
Теперь яиметь измерение с ~ 43 миллионами точек. Попытка изменить состояние даже одной точки заканчивается исключением OutOfMemory .
Обработка выполняется для 3 измерений (содержащих каждые ~ 60k точек) и разбивается на 4-е,очень большое измерение: метод save () работает вечно, пока я не получу OOM.
Stack
Sprint Boot 1.5.16.RELEASE с 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 ГБ, и через несколько минут я получу OOME.
Вопрос
Как можно избежатьOOM и почему общее количество элементов страницы имеет какое-либо значение?Я думал, что только размер страницы влияет на количество данных, загружаемых в память.
Профилирование
Обновление
Когда я сбрасываю состояние точки (обработано = ложь), обработка повторяется до измерения 4, и затем я вижу то же самое поведение.
Я могу обновить точки вручную в базе данных без проблем.