2009-11-02 9 views
3

파일 저장소가있는 웹 응용 프로그램이 있습니다. 이 웹 응용 프로그램은 클라이언트가 저장소를 검색하고 SOAP를 통해 첨부 파일을 다운로드 할 수있는 웹 서비스를 제공합니다.Java에서 웹 서비스를 통해 대용량 파일 다운로드

현재 MTOL과 함께 Spring-WS 1.5.8을 사용하여 클라이언트에 첨부 파일을 보내려고했지만 메모리 오류가 계속 발생합니다. 내 서버에 8GB의 메모리가 있고 Tomcat에서 4GB를 사용하도록 구성했기 때문에 이러한 오류가 Tomcat 6 인스턴스와 관련이 있다고 생각하지 않습니다. 200MB 크기의 파일에 이러한 오류가 발생합니다.

SOAP을 사용해야합니다. 아마 최선의 방법은 아닙니다. 나는 봄에 해결책을 선호 하겠지만, 가능하지 않다면 다른 생각을 할 수있다. AxiomSoapMessageFactory를 사용하여 업로드 목적으로 서버에 파일을 스트리밍 할 수 있지만 다른 방법은 사용할 수 없다는 것을 읽었습니다. 사실입니까? 자바

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

코드를 게시 할 수 있습니까? 귀하의 시간 초과는 어떻게 설정됩니까? –

+0

OutOfMemoryErros는 * 어디에서나 * 표시되지만 메모리 포옹이 실제로 필요한 곳에서는 필요하지 않습니다. 메모리 누수가있는 다른 응용 프로그램을 실행중인 경우 체인에서 마지막 응용 프로그램이므로 응용 프로그램이 다운 될 수 있습니다. – mhaller

답변

3

에덴 공간이 작아 질 수 있습니다. 에덴 공간은 힙에서 새로운 객체가 할당되고 GC에서 살아남을 때까지 남아있는 부분입니다. 에덴 공간은 그다지 크지 않습니다. (기본 값은 없지만 1GB 힙이있는 기본 설정에서는 단지 64MB입니다)

파일이 eden 공간에로드 될 것입니다. 200MB의 여유 공간이 없거나 바이트 배열이 작게 할당되어 커질 필요가 있습니다. Java에서 배열을 탐색하는 유일한 방법은 새롭고 더 큰 배열을 할당하고 memcopy를 수행하는 것입니다. 100MB에서 200MB로 증가 할 때마다 300MB의 전체 힙 힙 공간이 필요합니다.

-XX:NewSize=4196M을 설정하면 4GB의 힙 힙 공간을 할당 할 수 있습니다.

Tomcat이 다른 GC/힙 전략을 사용하는 일부 서버 모드에서 실행되고 있다는 것을 알 수 있습니다.

당신은 jvmstat 3.0에서 visualgc 사용할 수 있습니다 (안 자바 5와 함께 번들로 배포를 6) 힙을들을 모니터 전체 실행되고있는 힙 공간을 확인합니다.

또한 체크 아웃 할 수 있습니다 :이 문제를 해결하는 경우 Tuning Garbage Collection with the 5.0 Java[tm] Virtual Machine

여전히 성능 저하는 A 확장하지 솔루션에 직면하게 될 것이다. 일종의 직접 스트리밍을 사용하면 더 나을 것입니다.그 목적을 위해 간단한 서블릿을 구현하는 것이 어렵지 않아야합니다.

2

SOAP/XML 많은 오버 헤드가 항상 정말하고 많은 메모리를 필요로 : 나는 여기에 내가 봄 WS 프레임 워크 내에서 점점 계속 오류가

자바 6을 사용하고 있습니다. 이 특별한 경우에는 스트림을 다른 종류의 OutputStream (ByteArrayOutputStream 이외)에 직접 쓰는 대신 메모리에 (너무 큰) byte []를 할당하려고합니다.

SOAP 인터페이스를 잊어 버리고 java.net.URLConnection을 사용하여 기본으로 돌아가서 더 자세히 작성해 보셨습니까? 이렇게하면 FileOutputStream을 사용하여 디스크에 직접 InputStream을 쓸 수 있습니다. FileOutputStream은 메모리에 전체를 저장하는 것보다 훨씬 효율적입니다.

0

전체 파일이 클라이언트로 전송 될 때 읽는 대신 메모리에서 처리하는 것처럼 보입니다.

URL을 만들어 실제 파일로 보내고 그대로두면 대신 웹 서버로 분기 할 수 있습니까?

관련 문제