2016-11-21 10 views
0

I Byte-Array haben, die als Datei zurück müssen, um das Frontend. Dazu verwende ich IOUtils.write aber wenn die Datei größer als 15-20MB ist werfen es: gescheitert; error = 'Speicher kann nicht belegt werden' (errno = 12) und mein Tomcat 7 stirbt.große PDF-Dateien OutOfMemoryError

Ich muss es neu starten zu arbeiten.

Tomcat mit 1,5 GB RAM und Dual-Core-CPU

Hier beginnt mein Code:

OutputStream outputStream = null; 
     try{ 
      outputStream = response.getOutputStream(); 
      IOUtils.write(imgbytes, outputStream); 
      outputStream.flush(); 
     }catch(IOException ioException){ 
      logger.error("IO ERROR - ", ioException); 
     }finally{ 
      if(outputStream != null){ 
       try { 
        outputStream.close(); 
       } catch (IOException e) { 
        logger.error("Error closing stream - ", e); 
       } 
      } 
     } 

Und hier ist der Fehler:

[2016-11-21 04:07:02] ERROR [http-bio-8080-exec-7] org.fwo.controller.FileController (FileController.java:43) - IO ERROR - 
ClientAbortException: java.net.SocketException: Connection reset 
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:413) 
    at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:371) 
    at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:438) 
    at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:426) 
    at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:91) 
    at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:84) 
    at org.apache.commons.io.IOUtils.write(IOUtils.java:1177) 
    at org.fwo.controller.FileController.getFile(FileController.java:40) 
    at sun.reflect.GeneratedMethodAccessor403.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:212) 
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126) 
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617) 
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578) 
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:900) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:827) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:620) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:427) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.net.SocketException: Connection reset 
    at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:118) 
    at java.net.SocketOutputStream.write(SocketOutputStream.java:159) 
    at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:215) 
    at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:480) 
    at org.apache.tomcat.util.buf.ByteChunk.append(ByteChunk.java:366) 
    at org.apache.coyote.http11.InternalOutputBuffer$OutputStreamOutputBuffer.doWrite(InternalOutputBuffer.java:240) 
    at org.apache.coyote.http11.filters.ChunkedOutputFilter.doWrite(ChunkedOutputFilter.java:119) 
    at org.apache.coyote.http11.AbstractOutputBuffer.doWrite(AbstractOutputBuffer.java:192) 
    at org.apache.coyote.Response.doWrite(Response.java:520) 
    at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:408) 
    ... 45 more 
started 
Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00000007c1780000, 95420416, 0) failed; error='Cannot allocate memory' (errno=12) 
# 
# There is insufficient memory for the Java Runtime Environment to continue. 
# Native memory allocation (malloc) failed to allocate 95420416 bytes for committing reserved memory. 
# An error report file with more information is saved as: 
# /tmp/hs_err_pid4983.log 
+0

Ich weiß, dass mein Gedächtnis nicht enought ist, aber ich suche nach Ideen, um den Prozess zu optimieren. Nicht jemand, mir zu sagen, "erhöhen Sie Ihren RAM" ... –

+0

Sie können interne Ausnahme erhalten, vielleicht informativ: \t Throwable t2 = t.getCause(); 15MB scheint nicht seltsam Nummer in 2016, auch in 1,5 GB (32bit?) Tomcat-Instanz –

+0

Vielleicht albernen Vorschlag: Gibt es ein Konfigurationslimit für einzelne Download? Ältere PHP (LAMP) -Konfigurationen hatten normalerweise solche Standardeinstellungen. Ich weiß nicht, was Bibliotheken tun, außer Tomcat. Viele Jahre funktioniert meine 32b Tomcat-Installation ohne ähnliches Problem. –

Antwort

1

Die Fehlermeldung sagt, dass Sie gehen native Speicher aus, so meine Vermutung ist, dass Sie eine 32-Bit-JVM unter Windows ausführen.

Ein 32-Bit-Prozess hat 4 GB Speicher und Fenster werden 2 GB in der Regel für sich behalten, so dass Sie mit 2 GB Arbeitsspeicher verbleiben. Ihr Heap benötigt 1,5 GB, so dass wenig Platz für den Off-Heap-Speicher verbleibt, in dem die native Zuweisung erfolgen soll.

Lösung: entweder Ihre Heap-Größe auf 1 GB reduzieren, um mehr Platz für die Off-Heap-Speicher oder zu einem 64-Bit-JVM zu machen.

+0

Wir laufen auf Digital Ocean Linux Maschinenserver mit 64-Bit Java. Server max ram Größe ist 2 GB und wir beginnen mit tomcat 1.5GB –

+0

Wenn diejenigen, 2GB eine harte Grenze zu den verfügbaren virtuellen Speicher sind, sollte es das gleiche Problem sein, also entweder erhöhen, dass Ihre Heap-Größe zu begrenzen oder reduzieren. –

+0

Ok, ich werde das tun, aber ich suche nach einer anderen Bibliothek oder Ansatz, weil, wenn dieses Stück Code mit großer Datei nicht ausgeführt wird, nur der Widder zu seinem Maximum wird, aber auch die CPU zu 70-80-100% gehen. –