我们需要发送非常大的SOAP消息(multiparts,MTOM),比如大约1或2 or。有时,该过程会以以下OOM结束:
java.lang.OutOfMemoryError: Java Heap Space
at java.util.Arrays.copyOf(Arrays.java:2479)
at java.io.ByteArrayOutputStream.toByteArray(ByteArrayOutputStream.java:203)
at com.ibm.ws.webservices.engine.transport.channel.OutboundOutputStream.toByteArray(OutboundOutputStream.java:100)
at com.ibm.ws.webservices.engine.transport.http.HttpOutboundChannelConnection.prepareHttpRequestHeaders(HttpOutboundChannelConnection.java:2027)
at com.ibm.ws.webservices.engine.transport.http.HttpOutboundChannelConnection.sendSOAPRequest(HttpOutboundChannelConnection.java:374)
at com.ibm.ws.webservices.engine.transport.http.HTTPSender.invoke(HTTPSender.java:745)
at com.ibm.ws.webservices.engine.PivotHandlerWrapper.invoke(PivotHandlerWrapper.java:264)
at com.ibm.ws.webservices.engine.PivotHandlerWrapper.invoke(PivotHandlerWrapper.java:264)
at com.ibm.ws.webservices.engine.WebServicesEngine.invoke(WebServicesEngine.java:336)
at com.ibm.ws.webservices.engine.client.Connection.invokeEngine(Connection.java:970)
at com.ibm.ws.webservices.engine.client.Connection.invoke(Connection.java:761)
at com.ibm.ws.webservices.engine.soap.SOAPConnectionImpl.call(SOAPConnectionImpl.java:223)
at com.ibm.ws.webservices.engine.soap.SOAPConnectionImpl.call(SOAPConnectionImpl.java:163)据我所知,这个问题是由于使用ByteArrayOutputStream造成的,它在处理非常庞大的流时看起来并不合适。
在堆栈跟踪之后,堆中至少需要两份完整消息内容(作为字节数组)的副本。
所以问题是,有没有人知道更好的SAAJ实现,通过堆消费的方式?或者可能是这个IBM实现的SAAJ的一些变通方法?
发布于 2017-01-19 06:03:54
假设IBM的SAAJ实现不是完全braindead的,我希望它只在未启用HTTP分块时才将消息转换为字节数组,并且在发送消息之前需要计算消息的长度。因此,首先要做的是确保启用了分块。
我不认为SAAJ定义了启用分块的标准方法,但是您可能想尝试在消息上设置相应的HTTP头:
soapMessage.getMimeHeaders().addHeader("Transfer-Encoding", "chunked");很有可能SAAJ实现会遵守这一点。
https://stackoverflow.com/questions/41694877
复制相似问题