Pregunta

Tengo una aplicación web sentado por ahí que es un repositorio de archivos. Esta aplicación web proporciona servicios web que permiten a los clientes a buscar en el repositorio y descargar cualquiera de los archivos adjuntos a través de SOAP.

Actualmente me han tratado de utilizar Primavera-WS 1.5.8 con masa máxima de despegue para enviar el archivo adjunto para el cliente, pero sigo obteniendo errores de memoria insuficiente. No creo que estos errores están relacionados con mi instancia de Tomcat 6 porque mi servidor tiene 8 GB de memoria y configurado para utilizar Tomcat 4 GB de eso. Me estoy haciendo estos errores en los archivos tan pequeños como 200 MB.

necesito utilizar SOAP, a pesar de que probablemente no es el mejor enfoque en absoluto. Yo preferiría una solución en la primavera, pero si eso no es posible, entonces estoy abierto a otras ideas. He leído que se puede utilizar el AxiomSoapMessageFactory para transmitir archivos en el servidor para subir propósitos, pero no al revés. ¿Es esto cierto? Estoy usando Java 6.

Aquí está el error que me siguen dando en el marco WS primavera:?

java.lang.OutOfMemoryError: Java heap space
    com.sun.xml.internal.messaging.saaj.util.ByteOutputStream.ensureCapacity(Unknown Source)
    com.sun.xml.internal.messaging.saaj.util.ByteOutputStream.write(Unknown Source)
    com.sun.xml.internal.messaging.saaj.packaging.mime.internet.BMMimeMultipart.find(Unknown Source)
    com.sun.xml.internal.messaging.saaj.packaging.mime.internet.BMMimeMultipart.readBody(Unknown Source)
    com.sun.xml.internal.messaging.saaj.packaging.mime.internet.BMMimeMultipart.getNextPart(Unknown Source)
    com.sun.xml.internal.messaging.saaj.packaging.mime.internet.BMMimeMultipart.parse(Unknown Source)
    com.sun.xml.internal.messaging.saaj.packaging.mime.internet.BMMimeMultipart.parse(Unknown Source)
    com.sun.xml.internal.messaging.saaj.packaging.mime.internet.MimeMultipart.getCount(Unknown Source)
    com.sun.xml.internal.messaging.saaj.soap.MessageImpl.initializeAllAttachments(Unknown Source)
    com.sun.xml.internal.messaging.saaj.soap.MessageImpl.getAttachments(Unknown Source)
    org.springframework.ws.soap.saaj.Saaj13Implementation.getAttachment(Saaj13Implementation.java:305)
    org.springframework.ws.soap.saaj.SaajSoapMessage.getAttachment(SaajSoapMessage.java:226)
    org.springframework.ws.support.MarshallingUtils$MimeMessageContainer.getAttachment(MarshallingUtils.java:109)
    org.springframework.oxm.jaxb.Jaxb2Marshaller$Jaxb2AttachmentUnmarshaller.getAttachmentAsDataHandler(Jaxb2Marshaller.java:532)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.MTOMDecorator.startElement(Unknown Source)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.InterningXmlVisitor.startElement(Unknown Source)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(Unknown Source)
    com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(Unknown Source)
    com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(Unknown Source)
    com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(Unknown Source)
    com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(Unknown Source)
    com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(Unknown Source)
    com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(Unknown Source)
    com.sun.xml.internal.bind.unmarshaller.DOMScanner.visit(Unknown Source)
    com.sun.xml.internal.bind.unmarshaller.DOMScanner.scan(Unknown Source)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(Unknown Source)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(Unknown Source)
    javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(Unknown Source)
    org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshal(Jaxb2Marshaller.java:421)
    org.springframework.ws.support.MarshallingUtils.unmarshal(MarshallingUtils.java:62)
    org.springframework.ws.client.core.WebServiceTemplate$3.extractData(WebServiceTemplate.java:374)
    org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:560)
¿Fue útil?

Solución

Podría tener algo que ver con su espacio eden ser a pequeña. El espacio eden es la parte de la pila donde nuevo objeto se asignan y permanecen hasta que han sobrevivido a un GC. El espacio eden es no muy grande. (I no tienen un valor por defecto, sino en la configuración por defecto con 1 GB montón que está a sólo 64 MB)

Su archivo probablemente será cargado en el espacio de Edén. O bien no hay 200 MB de espacio libre o la matriz de bytes se asigna a las pequeñas y necesita para crecer. La única manera de que una serie de hRow en Java es mediante la asignación de un nuevo y más grande matriz y hacer un memcopy. Esta voluntad El crecimiento de 100 MB a 200 MB requiere obviamente 300 MB de espacio total eden montón.

Usted podría intentar establecer -XX:NewSize=4196M que destinará 4 GB de espacio eden montón.

Tengo que decir, que yo no conozco i Tomcat se ejecuta en algún modo de servidor, que utiliza una estrategia diversa GC / montón.

Puede usevisualgc de jvmstat 3.0 (no incluido con la distribución de Java 5 y 6 ) para supervisar el montón un determinar qué espacio de almacenamiento dinámico se ejecuta completa.

Es posible que también desee comprobar hacia fuera: recolección de elementos href="http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html" Sintonía con el 5.0 de Java [TM] virtual Machine

Si resuelve este problema que tendrá que enfrentarse a un mal desempeño de una solución no escalable. Es probable que sea mejor con algún tipo de transmisión en directo. No debería ser difícil de implementar un servlet simple para ese propósito.

Otros consejos

SOAP / XML en Java tiene siempre realmente un montón de gastos generales y necesita una gran cantidad de memoria. En este caso específico se está tratando de asignar una (demasiado grande) byte [] en la memoria en lugar de escribir la corriente directamente a otro tipo de OutputStream (cualquier cosa menos ByteArrayOutputStream).

¿Ha considerado olvidar la cosa interfaz SOAP del todo y volver a lo básico usando java.net.URLConnection y construir sobre eso más? De esta manera se puede escribir el InputStream directamente en el disco utilizando FileOutputStream que es mucho más eficiente que el almacenamiento de toda la cosa en la memoria.

Parece que está manejando el archivo completo en la memoria en lugar de leerlo, ya que se envía al cliente.

Se puede divergir esta al servidor web en lugar si se crea una URL que se resuelve con el archivo existente para enviar y dejarlo a él?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top