首页 > 解决方案 > Spring Boot Jackson 占用大量内存

问题描述

Spring Boot 需要大约 3 GB 内存来将 300 mb 有效负载转换为对象

POST我发送到 Spring Boot Web 应用程序的请求有效负载是 300 mb。但是 SpringBoot 应用程序 esp Jackson 解析器正在讨论 3gb 的内存来将请求映射到其相应的对象。

由于这个问题,我直接读取流,并且我编写了自定义解析器来解析有效负载并将其映射到对象。

JSON形式的payload如下:

{"a": "some value", "b": "this value is around 300 mb string"}

为什么 Springboot Jackson 解析器占用 3 GB 内存将 JSON 有效负载映射到对象?我没有编写任何自定义代码,我相信 SpringBoot 内部使用 Jackson 将 JSON 映射到 Object。

SpringBoot 或 Jackson 解析器是否适合解析 300 mb 的有效负载?

注意:我的 JSON 有效负载中只有一个元素约为 300 mb。

标签: javajacksonspring-data-jpa

解决方案


假设 JSON 是大多数 ASCII 字符,那么您的有效负载都是 1 字节字符。Java 字符串是 UTF-16 编码的,所以每个字符是 2 个字节。

这意味着您的 300 mb 有效负载是 600 Mbchar[]的内存。

由于有效负载主要是 JSON 字符串文字,因此需要提取,即复制该文字。由于大小未知,因此很可能将其复制到StringBuilder. 那StringBuilder将有一个 600 Mb char[],然后从中创建一个字符串,即另一个 600 Mb char[]

因此,简单地提取字段的字符串值b将消耗 600 Mb 的 3 倍。即 1.8 Gb 的内存,你甚至还没有开始为你的对象分配内存。

当然,在开始之前,它StringBuilder有资格进行 GC,但在开始创建 POJO 之前,您仍然消耗了 1.2 Gb 的内存。


推荐阅读