我正在尝试使用SpringBoot JPA将大约100k项(实体)插入数据库。但是JVM内存不足。
try (Stream<Path> paths = Files.walk(Paths.get(this.folderPath))) {
paths.filter(Files::isRegularFile).map(Parser::parse).forEach(item -> {
log.debug("Load trade : " + item.getId());
itemService.save(item);
});
}
其中itemService是使用ItemRepository的服务,而ItemRepository是JPA存储库:
ItemRepository extends JpaRepository<Item, String> {}
在applicateion.yml中,我进行了以下设置,希望这可以避免内存泄漏:
jpa:
properties:
hibernate:
generate_statistics: true
jdbc.batch_size: 2000
我的理解是,它将每2000个实例执行批量插入,并在每次批量插入后释放内存。但是,我仍然遇到内存不足的异常。在我看来,itemService可以支撑所有交易,因此不执行任何GC。
我是JPA的新手,请问有人可以为避免内存泄漏而做些什么?
赞赏。
答案 0 :(得分:1)
您必须使用saveAll
方法才能使批处理更新生效。
例如
try (Stream<Path> paths = Files.walk(Paths.get(this.folderPath))) {
List<Path> files = paths
.filter(Files::isRegularFile)
.collect(Collectors.toList());
for (List<Path> batch : Lists.partition(files, 2000)) { // Lists from Guava, batch will be 2000 elements or less.
List<Item> parsed = batch.stream().map(Parser::parse).collect(Collectors.toList());
itemService.saveAll(parsed);
}
}
答案 1 :(得分:0)
为了处理您的批处理,缺少了用于重写批处理插入方式的其他配置:
jdbc:postgresql://localhost:5432/yourDB?reWriteBatchedInserts=true