Hi André,

> -----Original Message-----
> From: André Warnier [mailto:a...@ice-sa.com]
> Sent: Thursday, July 14, 2011 1:00 PM
> To: Tomcat Users List
> Subject: Re: AJP-APR failures on Tomcat 7.0.16 with ISAPI Redirector
> 1.2.32
> 
> As a comment purely from a general programming point of view, not a
> Java/Tomcat
> programming point of view :
> 
> I am not familiar with the ByteArrayOutputStream, but from your usage
> of it above it seems
> to be a buffer in memory to which one can write, and with a special
> "writeTo" method which
> must be an efficient way to copy its contents to another stream.
> 
> If so, whether it is good practice or not would depend entirely on your
> particular
> circumstances : the size of the images you are handling this way, the
> number of
> simultaneous requests which you are handling, how much memory you have
> to play with, and
> how fast your CPU is.
> It is sometimes surprising to make the calculation.
> 
> (...)
> 
> So, compared to using the Response output stream directly, you would
> now use an additional
> (375 KB X 400) = 150,000 KB = about 150 MB additional Heap space
> 
> That seems reasonable to me.
> But of course it would be a problem if you are currently running Tomcat
> with a 128 MB heap.
> Or if your images, instead of being 250 KB on average, would be 250 MB.
> Or if filling up - and reading back - the ByteArrayOutputStream was
> very inefficient and
> used up all your CPU time.
> 
> On the other hand, the alternative is to have broken responses, so it
> may be better to add
> some RAM to the system.
> 


Thanks for your long response.

Your assumption about ByteArrayOutputStream is correct: It buffers the
contents written to it in a byte array, which automatically grows if its
capacity is exceeded, by factor 2.

However I think the memory is not a big issue here, because the data that is
written to the ByteArrayOutputStream is the compressed version of an image
that is already in RAM, and that is usually much bigger than the compressed
form. For example, when I have a BufferedImage of 800x600 pixel and 24 bit
per pixel (TYPE_INT_RGB), it consumes 800*600*3 bytes = 1,37 MiB in memory.
The size of the compressed form varies from file type (JPEG, PNG, ...) and
the contents of the image, but if I would save it as JPEG for example, it
will only take about 200 KiB, which is much less than the uncompressed form
in the memory.

An alternative that I could imagine, would be to create a class (that has a
boolean flag) which extends OutputStream, and decorates another OutputStream
that is given to the class in the constructor (that would be the
OutputStream from the servlet's response). This class would pass all calls
to it to the other OutputStream (as long as the flag is true), and as soon
as close() or another special method is called, it sets the flag to false,
which causes all other methods to do nothing (or throw an IOException). That
way, Tomcat's OutputStream would also be protected from future calls from
the ImageIO.


I agree that this behavior of the ImageIO is very strange (flushing the
OutputStream when the ImageWriter gets garbage-collected, if an IOException
was thrown when the IIO previously tried to write to the stream). However,
it seems also a bit strange to me that Tomcat is recycling OutputStreams,
because in my understanding, once an OutputStream is closed, it should be
impossible to do any further write() calls to it.

May I ask, what is the particular reason for Tomcat to recycle
OutputStreams?


Thanks!

Regards,
Konstantin Preißer


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org

Reply via email to