Reputation: 1
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!
Upvotes: 0
Views: 758
Reputation: 23014
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/
Upvotes: 0
Reputation: 3767
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.
Upvotes: 1