Ошибка нехватки памяти при сортировке больших вложений - PullRequest
1 голос
/ 29 апреля 2011

Я использую 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-версия "1.6.0_24" Java (TM) SE Runtime Environment (сборка 1.6.0_24-b07-334-10M3326) Java HotSpot (TM) 64-разрядная серверная виртуальная машина (сборка 19.1-b02-334, смешанный режим)

Ответы [ 3 ]

1 голос
/ 29 апреля 2011

Полагаю, вам нужно установить для свойства attachmentCaching значение true. По умолчанию установлено значение false.

1 голос
/ 29 апреля 2011

Отключает это из-за включения трассировки сообщений.Когда трассировка сообщений включена, 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");
}
1 голос
/ 29 апреля 2011

Вы пытались изменить следующие параметры, чтобы увеличить объем памяти?

-Xms512m -Xmx1024m -XX: PermSize = 256m

...