【问题标题】:Out of memory error when marshalling large attachments编组大型附件时出现内存不足错误
【发布时间】:2011-04-28 22:39:32
【问题描述】:

我在服务器端使用带有 AxiomSoapmessageFactory 的 spring ws:

<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)

问题似乎是服务试图在将整个附件写出之前将其读入内存。有没有办法流式传输附件?

我在 OSX 10.6.7 java --version = 的 Tomcat 实例中运行它

java 版本“1.6.0_24” Java(TM) SE 运行时环境 (build 1.6.0_24-b07-334-10M3326) Java HotSpot(TM) 64 位服务器 VM(内部版本 19.1-b02-334,混合模式)

【问题讨论】:

    标签: java spring soap spring-ws axiom


    【解决方案1】:

    您是否尝试更改以下参数以允许更多内存?

    -Xms512m -Xmx1024m -XX:PermSize=256m

    【讨论】:

    • 我必须处理分配给服务器的堆空间量,所以我无法增加堆空间量,我需要流式传输附件
    【解决方案2】:

    我认为您需要将 attachmentCaching 属性设置为 true。默认为假。

    【讨论】:

    • 这完全正确。结果证明这是我下一个内存不足错误的解决方案。
    【解决方案3】:

    原来这是由打开消息跟踪引起的。当消息跟踪在 MessageSender 上时(至少在 spring-ws 1.5.9 中)尝试将整个消息复制到 ByteArrayOutputString 中,然后将整个内容转换为字符串。有问题的函数是 MessageSender.recieve 和 MessageSender.getContent

      public void receive(MessageContext messageContext) throws Exception {
        // Let's keep a reference to the request content as it came in, it might be changed by interceptors in dispatch()
        String requestContent = "";
        if (receivedMessageTracingLogger.isTraceEnabled()) {
            requestContent = getMessageContent(messageContext.getRequest());
            receivedMessageTracingLogger.trace("Received request [" + requestContent + "]");
        }
        else if (receivedMessageTracingLogger.isDebugEnabled()) {
            receivedMessageTracingLogger.debug("Received request [" + messageContext.getRequest() + "]");
        }
        dispatch(messageContext);
        if (messageContext.hasResponse()) {
            WebServiceMessage response = messageContext.getResponse();
            if (sentMessageTracingLogger.isTraceEnabled()) {
                String responseContent = getMessageContent(response);
                sentMessageTracingLogger.trace("Sent response [" + responseContent + "] for request [" +
                                requestContent + "]");
            }
            else if (sentMessageTracingLogger.isDebugEnabled()) {
                sentMessageTracingLogger.debug("Sent response [" + response + "] for request [" +
                        messageContext.getRequest() + "]");
            }
        }
        else if (sentMessageTracingLogger.isDebugEnabled()) {
            sentMessageTracingLogger
                    .debug("MessageDispatcher with name '" + beanName + "' sends no response for request [" +
                            messageContext.getRequest() + "]");
        }
    
        private String getMessageContent(WebServiceMessage message) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        message.writeTo(bos);
        return bos.toString("UTF-8");
    }
    

    【讨论】:

      猜你喜欢
      • 2014-05-10
      • 1970-01-01
      • 1970-01-01
      • 2021-04-23
      • 2016-01-09
      • 2019-08-23
      • 2012-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多