Re: Could this unclosed() byteArrayInputStream cause high Heap usage ?
In article
<65da124a-3abd-4d57-9660-3c25784abe63@p13g2000pre.googlegroups.com>,
Krist <krislioe@gmail.com> wrote:
Hi all,
As part of our reporting integrated with our JSF/JSP application, the
report is converted to PDF then sent to browser for user to display.
mean while during peak load our Heap usage could reach 3.5GB - 4GB. So
I am suspecting the unclosed byteArrayInputStream is the cause.
(This is a production application so I am collecting information
before change the code)
Is the unclosed() byteArrayInputStream really cause the problem ?
(the codes is below)
Thank you,
Krist
ByteArrayInputStream byteArrayInputStream = (ByteArrayInputStream)
reportClientDoc.getPrintOutputController().export(exportOptions);
reportClientDoc.close();
writeToBrowser(byteArrayInputStream, response, "application/csv",
EXPORT_FILE);
private void writeToBrowser(ByteArrayInputStream byteArrayInputStream,
HttpServletResponse
response, String mimetype, String exportFile)
throws Exception {
byte[] buffer = new byte[byteArrayInputStream.available()];
int bytesRead = 0;
response.reset();
response.setHeader("Content-disposition", "inline;filename=" +
exportFile);
response.setContentType(mimetype);
//Stream the byte array to the client.
while((bytesRead = byteArrayInputStream.read(buffer)) != -1)
{ response.getOutputStream().write(buffer , 0,
bytesRead);}
//Flush and close the output stream.
response.getOutputStream().flush();
response.getOutputStream().close();
}
This probably isn't where your memory is going. Turn on object
histogram dumps then send a QUIT signal when memory is high.
On the other hand, the code is bad:
Casting the InputStream to an implementation is prone to failure. Don't.
byte[] buffer = new byte[byteArrayInputStream.available()];
InputStream.available() returns a value between 0 and the entire size of
the data. It's for avoiding blocking I/O and aligning buffers. It's
not for setting up a constant buffer size. In the case of
ByteArrayInputStream, it's the entire size of the data. Another
implementation might return zero and then you'd infinite loop. Use a
constant, like 2048 for WAN or 65536 for LAN.
If the PrintOutputController belongs to you, consider modifying it to
write directly to an OutputStream. This will eliminate intermediate
buffering and provide a faster first-byte response. The downside is
that the PrintOutputController could be active and holding resources for
a very long time if the client is on dialup. Which is best depends on
the application.
--
I won't see Google Groups replies because I must filter them as spam