Java.lang.OutOfMemoryError:

I am trying to create video files from bytes received from a database. The program worked up to several hours. After downloading a large file, when I try to restore it, it creates a java.lang.OutOfMemoryError: 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:

 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 error says. What I need to fix in this ....... Thanks .....

+3
source share
9 answers

Here

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

You save the entire contents of the file in server memory. You know, one byte[] eats one byte of Java memory. If you have, for example, only 500 MB of memory and the file exceeds 500 MB, then you will get exactly this error. Please note that you will also receive it when 10 users simultaneously request a 50 MB video file. Thus, increasing the memory of Java, as suggested by other answers, is only a temporary solution and not very well thought out.

You need to get it in the flavor of InputStream instead, to internally allocate only a few (kilobytes) bytes as a stream buffer in memory instead of the entire contents of the file.

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

And write it to the desired output stream using IOUtils#copy() instead (don't forget to close them at the end!).

 FileOutputStream output = new FileOutputStream(file); try { IOUtils.copy(videoData, output); } finally { IOUtils.closeQuietly(output); IOUtils.closeQuietly(videoData); } 
+11
source

Since the size of your video files is large, it ended up all the memory on the heap. You need to increase the heap size by setting the VM arguments to -Xmx1024m. this will increase your heap space to 1 GB. If the problem still persists, you need to use java vm visualization to analyze which part of your program consumes more memory, and u shud - on other ways to reduce it. Increasing heap space over 1 GB is not a good solution to the heap space problem.

If you run your program from an IDE, such as setting up eclipse, set the ur configuration in configuration mode.

+2
source

The error says that you have lost your memory. You need to load less material into memory or increase the total amount of available memory.

+1
source

The error says:

 OutOfMemoryError: Java heap space 

You need more heap space: you can configure the virtual machine to use more heap space.

Option -Xmx

Example: -Xmx256m for a maximum heap space of 256 megabytes

+1
source

Use the -Xmx flag to increase the heap space allocated for your JVM. -Xmx1500m, for example.

If running from cli is easy

java -Xmx2000m youMainJavaFile

If you are running eclipse or the like, you need to go into the options and tell it to add this flag when running the JVM.

+1
source

Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector .

Oracle docs says, that means you have to increase the memory limit of your JVM, which runs your program. Heap size increase:

 JVM_ARGS="-Xmx1024m" 

This sets the heap size to 1024 MB. Or you can do this in your IDE in startup configurations by providing -Xmx1024m , as the VM option will work correctly.

+1
source

Inside IOUtils.write, use output.flush () so that the buffered bytes are written to the destination and the buffer is flushed. Nothing is left in the memory.

+1
source
 StringBuilder sb1 = new StringBuilder(); sb1.append(vid); String videoid=sb1.toString(); 

This is one way to do this, otherwise:

  String videoId = new String(new Integer(rs.getInt("videoid"))); 

Also find out what / how java heap space is allocated:

  -Xms<size> set initial Java heap size -Xmx<size> set maximum Java heap size -Xss<size> set java thread stack size 

To set the minimum heap to 64 MB and the maximum heap 256 MB for the HelloWorld Java program: java -Xms64m -Xmx256m HelloWorld If you use the IDE, you will have to change the settings when you start your server. NTN

+1
source

Your heap is too small to hold all the objects selected by your application.

The easiest solution is to increase the heap size . For instance. -Xms1g -Xmx1g

Or you can try to analyze the application to find out where the memory allocation comes from and optimize this code path.

0
source

Source: https://habr.com/ru/post/958953/


All Articles