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