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