Spring Boot需要大约3 gb的内存才能将300 mb有效负载转换为对象
我发送到Spring Boot Web应用程序的POST
请求有效负载为300 mb。但是SpringBoot应用程序esp Jackson解析器正在谈论3gb的内存,以将请求映射到其对应的对象。
由于这个问题,我直接读取流,并编写了自定义解析器来解析有效负载并将其映射到对象。
JSON形式的有效负载如下:
{"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左右。
答案 0 :(得分:4)
假设JSON是大多数ASCII字符,那么您的有效负载都是1字节字符。 Java字符串采用UTF-16编码,因此每个字符为2个字节。
这意味着您的300 mb负载是内存中的600 Mb char[]
。
由于有效载荷主要是JSON字符串文字,因此该文字需要提取(即复制)。由于大小未知,因此可能会将其复制到StringBuilder
中。 StringBuilder
将具有600 Mb char[]
,然后从中创建一个字符串,这是另一个600 Mb char[]
。
因此,仅提取b
字段的字符串值将消耗3倍600 Mb。即1.8 Gb的内存,您甚至还没有开始为对象分配内存。
当然,StringBuilder
在开始使用GC之前就可以使用GC,但是在开始创建POJO之前,您仍然消耗了1.2 Gb的内存。