java.lang.OutOfMemoryError:Java堆空间 - blobstoreService

时间:2013-03-05 17:22:12

标签: java google-app-engine google-cloud-storage

我正在尝试从存储在Google云端存储上的文件中读取字节并通过HTTP POST请求发送它但我使用更大的文件来解决此异常,代码正在运行小文件

此行引发了异常:

writer.write(blobstoreService.fetchData(new BlobKey(video.getBlobkey()), start, end));

这是我的代码:

    URLConnection connection = new URL("http://myurl.com/").openConnection();
    //set time out to infinite
    connection.setConnectTimeout(0);
    connection.setDoOutput(true);
    connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
    BufferedOutputStream writer = null;
    OutputStream output = connection.getOutputStream();
    writer = new BufferedOutputStream(output); // true = autoFlush, important!

    //........

    BlobInfoFactory blobInfoFactory = new BlobInfoFactory();
    BlobInfo blobInfo = blobInfoFactory.loadBlobInfo(new BlobKey(video.getBlobkey()));
    Long blobSize = blobInfo.getSize();
    //max read on fetch
    long maxReadFetch = 1015807;
    //read the file in one time temporary
    long i = 0;
    long start = 0;
    long end = 0;
    while(i < blobSize) {
        start = i;
        end = i + maxReadFetch;
        //determine end
        if(end > blobSize) {
            end = blobSize;
        } else {
            end--;
        }
        writer.write(blobstoreService.fetchData(new BlobKey(video.getBlobkey()), start, end));

        i += maxReadFetch;
    }
    writer.flush(); // Important! Output cannot be closed. Close of writer will close output as well.
} finally {
    if (input != null) try { input.close(); } catch (IOException logOrIgnore) {}
}

stacktrace:

  

来自servlet java.lang.OutOfMemoryError的未捕获异常:Java堆   java.util.Arrays.copyOf(Arrays.java:2961)中的空格   java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:111)     在   com.google.apphosting.utils.security.urlfetch.URLFetchServiceStreamHandler $连接$ BufferingOutputStream.write(URLFetchServiceStreamHandler.java:460)     在java.io.BufferedOutputStream.write(BufferedOutputStream.java:122)     在java.io.FilterOutputStream.write(FilterOutputStream.java:97)at   controller.CtrlWistia.upload(CtrlWistia.java:200)at   controller.CtrlWistia.add(CtrlWistia.java:126)at   controller.CtrlWistia.ajax(CtrlWistia.java:79)at   controller.CtrlAjax.main(CtrlAjax.java:66)at   vidaao.AjaxServlet.doPost(AjaxServlet.java:37)at   javax.servlet.http.HttpServlet.service(HttpServlet.java:637)at at   javax.servlet.http.HttpServlet.service(HttpServlet.java:717)at at   org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)     在   org.mortbay.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1166)     在   org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:176)     在   org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:145)     在   org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.java:92)     在   org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:394)     在   org.mortbay.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1157)     在   com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)     在   org.mortbay.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1157)     在   com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)     在   org.mortbay.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1157)     在   com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)     在   org.mortbay.jetty.servlet.ServletHandler $ CachedChain.doFilter(ServletHandler.java:1157)     在   org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)     在   org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)     在   org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)     在   org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)     在   org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)     在   com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:266)     在   org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)

1 个答案:

答案 0 :(得分:1)

请注意,即使您一次读取的内容少于1MB,您也要将该数据写入OutputStream,并保存在内存中,直到您提交请求为止。

根据docs

  

App Engine的URLConnection实现不会与远程主机保持持久连接。当应用程序设置请求数据或写入输出流时,请求数据将保留在内存中。当应用程序访问有关响应的任何数据时,例如获取输入流(或调用connect()方法),App Engine会使用请求数据调用URL Fetch服务,获取响应,关闭连接并返回响应数据