2016-12-12 5 views
0

サーバーからファイルをダウンロードする際に問題があります。それはこのようになります:1GB以上のファイルの場合Glassfish 3.1.2.2とOutOfMemoryError

response.reset(); 
    response.setContentType("audio/vnd.wave"); 
    File file = new File(filename); 
    FileInputStream stream = new FileInputStream(file); 
    long toWrite = file.length(); 
    filename = filename.substring(filename.lastIndexOf(File.separator) + 1, filename.length()); 
    response.setHeader("Content-disposition", "attachment; filename=\"" + filename + "\""); 
    //response.setHeader("Content-Length", String.valueOf(toWrite)); 
    response.setContentLength((int)toWrite); 
    response.getOutputStream().flush(); 
    response.flushBuffer(); 
    //Files.copy(file.toPath(), response.getOutputStream()); 
    byte data[] = new byte[1024*1024]; 
    int len; 
    while ((len = stream.read(data)) > 0) { 
     response.getOutputStream().write(data, 0, len); 
     response.getOutputStream().flush(); 
     response.flushBuffer(); 
     toWrite -= len; 
     System.out.println("left="+toWrite+" "+w.getBufferSize()+" "+w.getBytes().length); 
    } 
    stream.close(); 
    response.getOutputStream().flush(); 
    response.getOutputStream().close(); 
    context.responseComplete(); 

はそれが(この1つは1.4ギガバイト程度持っている)OOMEで終了します。ドメインの4GBのメモリを固定している

[#|2016-12-12T14:41:40.350+0100|INFO|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=99;_ThreadName=Thread-2;|left=389066752 8192 10737 
41824|#] 

[#|2016-12-12T14:41:41.237+0100|WARNING|glassfish3.1.2|javax.enterprise.resource.webcontainer.jsf.lifecycle|_ThreadID=99;_ThreadName=Thread-2;|#{showContractBean.downloadReco 
rding(item2.recFile)}: java.lang.OutOfMemoryError: Java heap space 
javax.faces.FacesException: #{showContractBean.downloadRecording(item2.recFile)}: java.lang.OutOfMemoryError: Java heap space 
     at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118) 
     at javax.faces.component.UICommand.broadcast(UICommand.java:315) 
     at javax.faces.component.UIData.broadcast(UIData.java:1093) 
     at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) 
     at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) 
     at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) 
     at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
     at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) 
     at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) 
     at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217) 
     at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:357) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217) 
     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279) 
     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 
     at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) 
     at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) 
     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161) 
     at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331) 
     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) 
     at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317) 
     at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195) 
     at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860) 
     at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757) 
     at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056) 
     at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229) 
     at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) 
     at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) 
     at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) 
     at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) 
     at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) 
     at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) 
     at com.sun.grizzly.ContextTask.run(ContextTask.java:71) 
     at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) 
     at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) 
     at java.lang.Thread.run(Thread.java:745) 
Caused by: javax.faces.el.EvaluationException: java.lang.OutOfMemoryError: Java heap space 
     at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102) 
     at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) 
     ... 37 more 
Caused by: java.lang.OutOfMemoryError: Java heap space 
     at java.util.Arrays.copyOf(Arrays.java:2271) 
     at java.io.ByteArrayOutputStream.grow(ByteArrayOutputStream.java:118) 
     at java.io.ByteArrayOutputStream.ensureCapacity(ByteArrayOutputStream.java:93) 
     at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:153) 
     at org.apache.myfaces.webapp.filter.ExtensionsResponseWrapper$MyServletOutputStream.write(ExtensionsResponseWrapper.java:141) 
     at com.agreeya.telekonferencje.web.ShowContractBean.downloadRecording(ShowContractBean.java:1569) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
     at java.lang.reflect.Method.invoke(Method.java:606) 
     at javax.el.BeanELResolver.invokeMethod(BeanELResolver.java:779) 
     at javax.el.BeanELResolver.invoke(BeanELResolver.java:528) 
     at javax.el.CompositeELResolver.invoke(CompositeELResolver.java:257) 
     at com.sun.el.parser.AstValue.invoke(AstValue.java:248) 
     at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:302) 
     at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) 
     at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) 
     at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) 
     at javax.faces.component.UICommand.broadcast(UICommand.java:315) 
     at javax.faces.component.UIData.broadcast(UIData.java:1093) 
     at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) 
     at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) 
     at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) 
     at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
     at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) 
     at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) 
     at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1550) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217) 
     at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:357) 
     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256) 
     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217) 

Serverは、NewRatioが2に設定されています(デフォルト値)。
あなたは私がこれまで試した見ることができるように各後のGlassFish
2.小規模/大きなバッファ配列
3.フラッシュ応答と出力ストリームの
1.より多くのメモリをファイルに
4.ん。ContentLengthを書きますサイズ
5.ストリームを直接コピーします(FileStream - > OutputStream)
6. Content-Lengthをヘッダとして直接設定します。
運がない。出力はストリームされるべきですが、そうではありません。

私は何を試すべきですか?

GFを4にアップグレードすることはできません。私は賛成です。

||

EDIT

が最後にそれが期待どおりに動作します:

FacesContext context = FacesContext.getCurrentInstance(); 
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse(); 
ExtensionsResponseWrapper responseWrapper = (ExtensionsResponseWrapper)response; 
HttpServletResponse delegateResponse = responseWrapper.getDelegate(); 

try { 
    response.reset(); 
    response.setContentType("audio/vnd.wave"); 
    File file = new File(filename); 
    long toWrite = file.length(); 
    filename = filename.substring(filename.lastIndexOf(File.separator) + 1, filename.length()); 
    response.setHeader("Content-disposition", "attachment; filename=\"" + filename + "\""); 
    response.setHeader("Content-Length", String.valueOf(toWrite)); 
    response.setContentLength((int)toWrite); 
    ServletOutputStream out = delegateResponse.getOutputStream(); 
    out.flush(); 
    response.flushBuffer(); 
    Files.copy(file.toPath(), out); 
    response.getOutputStream().flush(); 
    response.getOutputStream().close(); 
    context.responseComplete(); 
} catch (IOException ex) { 
    log.log(Level.SEVERE, ex.getMessage(), ex); 
} 

答えて

0

理由は、クラスExtensionsResponseWrapperがByteArrayOutputStreamに出力を書き込みことで、コードhereを参照してください。

これは標準のMyFacesレスポンスかどうかわかりませんが、アプリ/ GlassFishの設定が原因で使用されています。 responseオブジェクトを作成または受信するコードを確認します。

+0

ByteArrayOutputStream.flush()はノーオペレーションなので、ストリーミングする方法はありません。そして、私は[この投稿](http://stackoverflow.com/questions/24505635/buffering-response-in-heap-space-cause-problems-for-large-files)が見つからなかった。お手伝いありがとう。 – 13Homer