当Java对象变得太大时会发生什么?

当Java对象变得太大时会发生什么?,java,performance,object,server,heap-memory,Java,Performance,Object,Server,Heap Memory,由于客户端库中的一个非常愚蠢的错误,我们的生产系统中出现了一个特殊的问题 发生的情况是: public <T> ResponseEntity<T> executePut(String url, JsonObject payload, Class<T> t) { String payloadString = payload != null ? payload.toString() : null; HttpEntity<Strin

由于客户端库中的一个非常愚蠢的错误,我们的生产系统中出现了一个特殊的问题

发生的情况是:

public <T> ResponseEntity<T> executePut(String url, JsonObject payload, Class<T> t) {
       String payloadString = payload != null ? payload.toString() : null;
       HttpEntity<String> entity = new HttpEntity<>(payloadString, getCommonHeaders());
       restTemplate.getMessageConverters()
               .add(0, new StringHttpMessageConverter(Charset.forName("UTF-8")));
       return restTemplate.exchange(url, HttpMethod.PUT, entity, t);
   }
public ResponseEntity executePut(字符串url,JsonObject负载,类t){
字符串payloadString=payload!=null?payload.toString():null;
HttpEntity=新的HttpEntity(payloadString,getCommonHeaders());
restemplate.getMessageConverters()
.add(0,新的StringHttpMessageConverter(Charset.forName(“UTF-8”));
返回restemplate.exchange(url,HttpMethod.PUT,entity,t);
}
从上面的方法中可以看出,客户机库获取了autowired(singleton)对象,并继续在MessageConverters列表中添加元素

问题:过了一会儿,对restTemplate对象的引用也给了NPE一个空堆栈跟踪。

PS:我指出这是可能的原因,因为这是两个部署之间发生的唯一代码更改


此外,大对象不应该导致内存堆不足吗?在我们的例子中,这种情况也没有发生,其他应用程序流工作正常。

当一个对象变得太大,以至于占用了所有堆内存时,VM将停止正常工作。在此VM中运行的程序的任何部分都不可能保持正常工作

当堆已满时,垃圾收集器将尝试释放内存。他会一直这样做。你的虚拟机将不再做其他事情。而且您很可能会得到
OutOfMemoryError:GC开销限制超过了
。看

程序中的代码不应处理此错误。如果出现内存不足错误,则不太可能有人返回
null
。我会考虑这种非常恶劣的行为。

关于NullPointerException:我不认为它没有堆栈跟踪。不过,它可能不会被记录。您是否尝试将调试器附加到系统并为NPE设置异常断点


REST模板中的所有消息转换器都将逐个调用。每次调用时,您都会将消息转换器添加到列表的开头。这对我来说似乎没有意义。这可能会在内部造成麻烦。

我认为我的问题与您链接中的问题有细微的不同,他显然是内存不足,但我没有得到这样的例外。当内存不足时,堆栈跟踪可能不会显示(因为没有足够的内存)。那么,是什么让您认为您的问题与堆内存有关?我看不出有任何迹象表明这一点。尝试使用调试器并搜索引发NPE的位置。如果您发现了更多信息,请调整您的问题。@JochenReinhardt我就是这么说的,我没有理由相信这是堆问题,因为应用程序似乎工作正常。我的问题是试图理解是什么导致了这个问题?当然,它会在内部造成麻烦。他已经知道了。我不确定这是否回答了我的问题,无论如何,非常感谢你的努力:)你实际上问了如果java对象变得太大会发生什么。我想我回答了这个问题。不过,您仍然需要调查程序失败的原因。但实际上你并没有要求。