java. lang.OutOfMemoryError:

I'm trying to create a video file from the bytes retrieved from the database The plan worked well a few hours ago After uploading a large file, when I try to retrieve it, it generates an error Java lang.OutOfMemoryError:

My code is:

conn = prepareConnection();
    StringBuilder sb=new StringBuilder(1024);
    sb.append("select videoname,videoid,videofull from ").append(uname.trim()).append("video");
    String sql=sb.toString();

    stmt = conn.prepareStatement(sql);
    ResultSet rs = stmt.executeQuery();

    while(rs.next()){
         byte[] videoData = rs.getBytes("videofull");       //#57
         int vid=rs.getInt("videoid");
         StringBuilder sb1 = new StringBuilder();
         sb1.append(vid);
         String videoid=sb1.toString();
         String vname=rs.getString("videoname");
         File file=new File("C:/Users/JamesPJ/Documents/skypark/skypark/WebContent/sp/resources/videos/"+vname+""+videoid+".mp4");

        if(file.exists() && !file.isDirectory()){
            continue;
        }
        else
        {
         FileOutputStream output = new FileOutputStream(file);
         IoUtils.write(videoData,output);
         output.close();
        }
       }
    request.setAttribute("uname",uname);
    RequestDispatcher dispatcher = request.getRequestDispatcher("/VideoList");
    if(dispatcher != null) {
        dispatcher.forward(request,response);
    }

Console output is:

Exception in thread "http-bio-8080-exec-3" java.lang.OutOfMemoryError: Java heap space
at oracle.sql.BLOB.getBytes(BLOB.java:217)
at oracle.jdbc.driver.T4CBlobAccessor.getBytes(T4CBlobAccessor.java:462)
at oracle.jdbc.driver.OracleResultSetImpl.getBytes(OracleResultSetImpl.java:716)
at oracle.jdbc.driver.OracleResultSet.getBytes(OracleResultSet.java:402)
at skypark.VideoFileCreator.doGet(VideoFileCreator.java:57)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:749)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:487)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:412)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:339)
at skypark.VideoStream.processRequest(VideoStream.java:48)
at skypark.VideoStream.doGet(VideoStream.java:64)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:931)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(UnkNown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(UnkNown Source)

Please tell me what this mistake tells me I need to correct it Thank you

Solution

here,

byte[] videoData = rs.getBytes("videofull");

You store the entire file content in the memory of the server You know, a byte of byte [] takes up a byte of JAVA memory If you have, for example, only 500MB of memory and files exceeding 500MB, you will get this error Please note that when 10 users request 50MB video files at the same time, you will also get it Therefore, as other answers show, increasing JAVA memory is only a temporary solution without careful consideration

You need to get it in the style of InputStream so that only a few (kilobytes) bytes are allocated internally as the stream buffer in memory instead of the entire file content

InputStream videoData = rs.getBinaryStream("videofull");

Then use ioutils #copy() to write it to the desired output stream (don't forget to close them in finally!)

FileOutputStream output = new FileOutputStream(file);
try {
    IoUtils.copy(videoData,output);
} finally {
    IoUtils.closeQuietly(output);
    IoUtils.closeQuietly(videoData);
}
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>