当我从 REST 服务获取大型 JSON 时,我收到 java.lang.OutOfMemoryError: Java heap space...这发生在 ~1000 次调用 REST 服务之后 HttpEntity
requestUpdate = new HttpEntity<>(request, httpHeaders); ResponseEntity messageEntity = restTemplate.exchange(getEndPointAddress(), HttpMethod.POST, requestUpdate, String.class); Map map = gson.fromJson(Helper.cleanJson(messageEntity.getBody()), Map.class);java.lang.OutOfMemoryError: Java heap space at java.util.Arrays.copyOfRange(Arrays.java:2694) ~[?:1.7.0_181] at java.lang.String.(String.java:203) ~[?:1.7.0_181] at java.lang.StringBuilder.toString(StringBuilder.java:405) ~[?:1.7.0_181] at org.springframework.util.StreamUtils.copyToString(StreamUtils.java:80) ~[stormjar.jar:4.0.3] at org.springframework.http.converter.StringHttpMessageConverter.readInternal(StringHttpMessageConverter.java:86) ~[stonjar.jar:4.0.3] at org.springframework.http.converter.StringHttpMessageConverter.readInternal(StringHttpMessageConverter.java:41) ~[stonjar.jar:4.0.3] at org.springframework.http.converter.AbstractHttpMessageConverter.read(AbstractHttpMessageConverter.java:193) ~[stonjar.jar:4.0.3] at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:104) ~[stonjar.jar:4.0.3] at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:884) ~[stonjar.jar:4.0.3] at org.springframework.web.client.RestTemplate$ResponseEntityResponseExtractor.extractData(RestTemplate.java:868) ~[stonjar.jar:4.0.3] at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:622) ~[stonjar.jar:4.0.3] at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:580) ~[stonjar.jar:4.0.3]
查看完整描述
TA贡献1829条经验 获得超7个赞
RestTemplate并且底层的 Spring bean 不是为流处理而设计的,它们ResponsEntity在内存中构建了整个。根据您的示例,您没有RestTemplate按预期使用。您正在阅读 String而不是将响应对象反序列化委托Map<String, Object>给底层转换器 bean。
如果 JSON 响应真的太大而无法放入您的堆中,您可以替换RestTemplate为URLConnection或任何其他可以让您InputStream直接访问响应的 HTTP 客户端库。这将允许您手动读取和解析响应,例如使用com.google.gson.stream.JsonReader:
URLConnection conn = // create and open
JsonReader reader = new JsonReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
// read manually using reader
String通过避免包含整个 JSON 主体的一个大对象,您将能够以这种方式节省内存。
查看完整回答