编组大型附件时出现内存不足错误
我在服务器端使用 spring ws 和 AxiomSoapmessageFactory:
<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
<property name="payloadCaching" value="true"/>
<!-- Need to figure out the appropriate directory -->
<property name="attachmentCacheDir" value="..."/>
</bean>
当服务接收消息时,这可以正常工作。但是,当服务尝试提供大消息时,我收到 Java 内存不足异常。这是堆栈跟踪:
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2786)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
at org.apache.axiom.mime.impl.axiom.MultipartWriterImpl$PartOutputStream.write(MultipartWriterImpl.java:42)
at javax.activation.DataHandler.writeTo(DataHandler.java:294)
at org.apache.axiom.mime.impl.axiom.MultipartWriterImpl.writePart(MultipartWriterImpl.java:116)
at org.apache.axiom.om.impl.OMMultipartWriter.writePart(OMMultipartWriter.java:136)
at org.apache.axiom.om.impl.MIMEOutputUtils.writeSOAPWithAttachmentsMessage(MIMEOutputUtils.java:269)
at org.springframework.ws.soap.axiom.AxiomSoapMessage.writeSwAMessage(AxiomSoapMessage.java:298)
at org.springframework.ws.soap.axiom.AxiomSoapMessage.writeTo(AxiomSoapMessage.java:248)
at org.springframework.ws.server.MessageDispatcher.getMessageContent(MessageDispatcher.java:192)
at org.springframework.ws.server.MessageDispatcher.receive(MessageDispatcher.java:174)
at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:88)
at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:57)
at org.springframework.ws.transport.http.ErrorAwareWebServiceMessageReceiverHandlerAdapter.handle(ErrorAwareWebServiceMessageReceiverHandlerAdapter.java:42)
at org.springframework.ws.transport.http.MessageDispatcherServlet2.doService(MessageDispatcherServlet2.java:148)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:680)
问题似乎是服务试图在将整个附件写出之前将其读入内存。有没有办法传输附件?
上的 Tomcat 实例中运行它
我在 OSX 10.6.7 java --version = java version "1.6.0_24" Java(TM) SE 运行时环境(内部版本 1.6.0_24-b07-334-10M3326) Java HotSpot(TM) 64 位服务器 VM(内部版本 19.1-b02-334,混合模式)
I'm using spring ws on the server side with a AxiomSoapmessageFactory:
<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory">
<property name="payloadCaching" value="true"/>
<!-- Need to figure out the appropriate directory -->
<property name="attachmentCacheDir" value="..."/>
</bean>
This works fine when the services are ingesting a message. However, when the services attempt to serve up a large message I get Java out of memory exception. Here is the stack trace:
java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOf(Arrays.java:2786)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94)
at org.apache.axiom.mime.impl.axiom.MultipartWriterImpl$PartOutputStream.write(MultipartWriterImpl.java:42)
at javax.activation.DataHandler.writeTo(DataHandler.java:294)
at org.apache.axiom.mime.impl.axiom.MultipartWriterImpl.writePart(MultipartWriterImpl.java:116)
at org.apache.axiom.om.impl.OMMultipartWriter.writePart(OMMultipartWriter.java:136)
at org.apache.axiom.om.impl.MIMEOutputUtils.writeSOAPWithAttachmentsMessage(MIMEOutputUtils.java:269)
at org.springframework.ws.soap.axiom.AxiomSoapMessage.writeSwAMessage(AxiomSoapMessage.java:298)
at org.springframework.ws.soap.axiom.AxiomSoapMessage.writeTo(AxiomSoapMessage.java:248)
at org.springframework.ws.server.MessageDispatcher.getMessageContent(MessageDispatcher.java:192)
at org.springframework.ws.server.MessageDispatcher.receive(MessageDispatcher.java:174)
at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:88)
at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:57)
at org.springframework.ws.transport.http.ErrorAwareWebServiceMessageReceiverHandlerAdapter.handle(ErrorAwareWebServiceMessageReceiverHandlerAdapter.java:42)
at org.springframework.ws.transport.http.MessageDispatcherServlet2.doService(MessageDispatcherServlet2.java:148)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:680)
The problem seems to be that the services are attempting to read the whole attachment into memory prior to writing it out. Is there a way to stream the attachment?
I'm running this in a Tomcat instance on OSX 10.6.7 java --version =
java version "1.6.0_24"
Java(TM) SE Runtime Environment (build 1.6.0_24-b07-334-10M3326)
Java HotSpot(TM) 64-Bit Server VM (build 19.1-b02-334, mixed mode)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您是否尝试过更改以下参数以允许更多内存?
-Xms512米
-Xmx1024米
-XX:PermSize=256m
Have you tried changing the following parameters to allow for more memory?
-Xms512m
-Xmx1024m
-XX:PermSize=256m
我相信您需要将 AttachmentCaching 属性设置为 true。默认为 false。
I believe you need to set the attachmentCaching property to true. The default is false.
事实证明这是由于打开消息跟踪引起的。当消息跟踪在 MessageSender 上时(至少在 spring-ws 1.5.9 中)尝试将整个消息复制到 ByteArrayOutputString 中,然后将整个消息转换为字符串。有问题的函数是 MessageSender.recieve 和 MessageSender.getContent
Truns out this was caused by turning message tracing on. When message tracing is on the MessageSender (at least in spring-ws 1.5.9) tries to copy the entire message into a ByteArrayOutputString and then converts the whole thing into a string. The offending functions are MessageSender.recieve and MessageSender.getContent