From: Krist on
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();
}
From: Roedy Green on
On Fri, 5 Feb 2010 03:21:04 -0800 (PST), Krist <krislioe(a)gmail.com>
wrote, quoted or indirectly quoted someone who said :

>Is the unclosed() byteArrayInputStream really cause the problem ?

It is a big array of characters that holds the entire stream. How
much of a problem it is unclosed depends on how big the stream it
holds is. It is just a StringBuilder in disguise. Is there any reason
you would NOT close the stream?
--
Roedy Green Canadian Mind Products
http://mindprod.com

You can�t have great software without a great team, and most software teams behave like dysfunctional families.
~ Jim McCarthy
From: Kevin McMurtrie on
In article
<65da124a-3abd-4d57-9660-3c25784abe63(a)p13g2000pre.googlegroups.com>,
Krist <krislioe(a)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
From: Krist on
On 6 Feb, 13:33, Kevin McMurtrie <mcmurt...(a)pixelmemory.us> wrote:
> In article
> <65da124a-3abd-4d57-9660-3c25784ab...(a)p13g2000pre.googlegroups.com>,
>
>
>
>
>
>  Krist <krisl...(a)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- Sembunyikan teks kutipan -
>
> - Perlihatkan teks kutipan -

Hi sir,

When will the memory taken by the byteArrayInputStream will be
released ?
Will it be garbage collected ?

Thanks,
Krist