eurotrans-Verlag wrote:
Hi Rainer,

-----Original Message-----
From: Rainer Jung [mailto:rainer.j...@kippdata.de]
Sent: Thursday, July 14, 2011 12:17 AM
At least there was trouble about Java2D for several users in the past.
One such issue:

https://issues.apache.org/bugzilla/show_bug.cgi?id=41772
http://nerd.dk/blogs/bug-tomcat-or-java2d

but you might find more.

Regards,

Rainer


Thanks. In the meantime, I also came to that conclusion and replaced all
instances of

ImageIO.write(img, "PNG", response.getOutputStream())

in my servlets/webapps with something like

ByteArrayOutputStream bout = new ByteArrayOutputStream();
ImageIO.write(img, "PNG", bout);
bout.writeTo(response.getOutputStream());

so that the ImageIO never sees the real OutputStream, and it seems to work
fine (no more IllegalStateExceptions or "wrong message format" errors in the
isapi log when using AJP-APR).

Is that a good practice (using ByteArrayOutputStream, then copy it to the
response) to dynamically generate Images and serve them to the clients?
Also, is there any hint to this on the Tomcat documentation/wiki? Because I
don't think it would be unusual to dynamically generate images and serve
them to clients using the ImageIO, and I think it could be a bit frustrating
to find the actual problem if one doesn't know this.


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.

By writing an image first to a memory buffer, you use up the additional memory of that buffer, which is equal to the output size of your image, plus the overhead of the ByteArrayOutputStream structure.

So let's use some totally arbitrary parameters, just for the sake of an example 
:
- let's say that ByteArrayOutputStream has 50% overhead. So to store 250 KB of data, in reality uses up 375 KB of RAM - you serve up to 100 basic browser page requests at a time (that is, the base html pages which include the images)
- each such page contains 4 (links to) images
- each image is on average 250 KB in size (a small jpeg)
- the browsers themselves, when finding image links in a page, will issue up to 4 simultaneous requests for those images (the last time I looked, quite a long time ago, browsers only requested 2 things in parallel, but they might have improved since)

So you could in theory have 400 simultaneous requests, for 400 images, each 250 
KB in size.
Thus your Tomcat server (supposing it can handle 400 threads at a time) would be creating 400 instances of ByteArrayOutputStream, and
- first filling them up until they reach 250 KB of data
- then copying this data back onto the Response output stream
- then discarding the ByteArrayOutputStream

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.

Note: the above calculation is probably quite questionable. But it provides a quick estimate, that may be roughly within a factor 10 of reality. I use this often at the beginning of a project, to at least get an idea whether something seems reasonable/feasible, or is totally off-kilter.

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

Reply via email to