java - Docker 中的 OOM,带有 Spring Boot + H2 + JPA 和批处理

标签 java spring-boot docker spring-data-jpa h2

java应用程序正在docker容器内运行。

rest Controller 和另一个微服务接收到的文档临时存储在内部 H2 数据库(在内存中)中。然后在 tika 的帮助下处理这些数据并将其发送到下一个微服务。最后文档将在内部数据库中删除。

这一切都按预期进行。数据库中的文档大小在处理过程中不断增加和减少(借助 H2 Web 控制台进行控制)。

持久文档的类如下所示:

@Entity
@Table(name = "Document")
public class Document {
@Id
@GeneratedValue
Long id = 0L;
@Lob
private String content;
@Lob
private String contentHtml = "";
@ElementCollection
@MapKeyColumn(name = "name")
@Column(length=1000, name = "value")
@CollectionTable(name = "meta_attributes", joinColumns = @JoinColumn(name = "meta_id"))
@LazyCollection(LazyCollectionOption.FALSE)
private Map<String, String> metadata;
@Enumerated(EnumType.STRING)
private DocStatus status;

public Document() {
}

但是问题是docker容器的内存消耗增加。我们尝试使用 MEMORY_MAX 为 3 GB 和 6 GB。在这两种情况下,内存使用量都会缓慢增加,直到容器以状态 137(已终止)退出。

处理大约50'000个文件后,表的状态如下:

enter image description here

在 jmap 的帮助下制作的有关容器内 jvm 的转储显示,大部分内存被 MVMap (PageReferences) 消耗,这似乎是 H2 用于存储数据的:

enter image description here

enter image description here

我的问题:

这更有可能是 H2 内部的一种内存泄漏,还是更有可能是配置问题?我尝试的是将使用的 JPARepository 方法从 .save() 更改为 .saveAndFlush() ,这没有改变任何内容。我无法想象这与实体管理器有关,因为这都是由 Spring Boot 管理的。

最佳答案

最可能的原因是您没有调用 commit(),这意味着旧版本的数据永远不会被刷新

关于java - Docker 中的 OOM,带有 Spring Boot + H2 + JPA 和批处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60553443/

相关文章:

java - hibernate 不保存值的集合

spring - RestController 返回 CompletableFuture<List>

docker - 使用 docker compose 连接 2 个 docker 容器

node.js - 如何升级 docker 容器内的 npm?

java - 如何传递参数化 lambda 的构造函数引用?

java - Apache:Tomcat "any version".exe 或 .zip

java - Spring安全5/Spring Boot 2.2 : No AuthenticationProvider found for org. springframework.security.authentication.UsernamePasswordAuthenticationToken

java - cvc-复杂类型.2.4.a : Invalid content was found starting with element 'beans'

docker - gcloud docker 推送可靠性

java - 使用单独的元素和其他列表中的元素填充 java 列表的最佳方法是什么?