简体   繁体   中英

outOfMemory java heap space error on tomcat server, not appearing locally

I'm building a web-site using Java Spring and Hibernate and using Tomcat 7 as server. I have a page of this site where, once the user clicks on an image other two images are loaded. The workflow is the following:

Image Clicked -> Calculation(spring method) -> Images saved on the server as jpg -> Images updated from the server and showed to the client.

The images are loaded like follows:

    response.setContentType("image/jpg");
    OutputStream out = response.getOutputStream();  
    FileInputStream in = new FileInputStream(xzCrossUrl);  
    int size = in.available();  
    byte[] content = new byte[size];  
    in.read(content);  
    out.write(content);  
    in.close();  
    out.close();

I know this probably is not the best way to doing it, but I have not much experience yet.

Locally it works fine, but when I put the .war on the tomcat directory and connect to the server, a Java outOfMemory heap space problem is coming out, and the images are loaded much slower than locally.

I tried to increase the memory used by tomcat but it seems not to work; maybe I'm doing something wrong.

Can you please help me with this?

Thank you very much in advance!

I can't put this in a comment because I don't have enough cred, so...

While it may be something you can fix with the Tomcat configuration, what code you have will not scale for any image. You should declare the byte[] to be a fixed size and then read and write until you've consumed all of the file bytes:

// as a class scoped constant
private static final int BUFFERSIZE = 1024 << 8;

 BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream(), BUFFERSIZE); BufferedInputStream in = new BufferedInputStream(new FileInputStream(xzCrossUrl)); int bytesRead = 0; byte[] content = new byte[BUFFERSIZE]; while((bytesRead = in.read(content) != -1){ out.write(content,0,bytesRead); } // Don't forget appropriate exception handling with a try/finally! in.close(); out.close(); 

FYI: I wrote this here, not in an IDE and have not compiled it, so my apologies if isn't perfect. Hopefully you get the gist.

How about using IOUtils.copy() from the Apache Commons IO package - which will copy the input stream to the output stream and will buffer internally so you don't have to.

response.setContentType("image/jpg");
OutputStream out = response.getOutputStream();  
FileInputStream in = new FileInputStream(xzCrossUrl);  
IOUtils.copy(in, out);

IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);

For larger files you can use IOUtils.copyLarge()

For more info on Commons IO see http://commons.apache.org/proper/commons-io/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM