Name: ks88420 Date: 09/13/2000
java version "1.3.0beta_refresh"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0beta_refresh-b09)
Java HotSpot(TM) Server VM (build 1.3.0beta-b07, mixed mode)
Every time a String is created or written a new call to the synchronized methods
in sun.io.Converters for creating is made creating a rather bad competition for
these monitors resulting in poor CPU utilization when run with any non-trivial
number of threads. A thread dump reveals that EVERY ONE of our 64 servlet worker
threads (which I think is a very modest figure) is waiting for one of the two
monitors shown below.
The caching of the last ByteToCharConverter and CharToByteConverter doesn't seem
to work. This is consistent with what we've seen when we've tried to use
SoftReference:s to cache things ourselves. They seem to be garbagecollected
"wap-servlet-71" prio=1 tid=0x81bd430 nid=0x6c88 waiting for monitor entry
"wap-servlet-4" prio=1 tid=0x81920f0 nid=0x6b54 waiting for monitor entry
(Review ID: 109577)
Name: krC82822 Date: 01/07/2001
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)
We recently switched from 1.1.8 to 1.3 and noticed a change
in the behavior of some constructors of the String class.
Synchronization has been introduced in the class sun.io.Converters,
which impacts the performance of software that uses Strings.
Here is a portion of a stack trace showing the monitor in question:
"HttpHandler-374" prio=5 tid=0x20b5100 nid=0x1a0 waiting for monitor entry [0xbe
In a threaded server app (anywhere from 20-400 threads) we see 90%
or more of the threads are waiting for this monitor at any one
time, making it impossible to saturate the CPU on test machines.
This severely limits the performance of the server.
We found that the caching of the last converter that is performed in
the String class helps a little, but one has to be very careful or
it is easily defeated. The test done there calls
ByteToCharConverter.getCharacterEncoding to compare to the passed in
encoding, but that method does not always return the encoding name
that was used to get that converter! For example, if you pass in
an encoding of "8859_1", the returned converter will tell you that its
name is "ISO8859_1". The next time you ask for "8859_1", String will
not realize this is the same converter, and will fetch it again, defeating
the cache. We found that by making sure we use the canonical name for the
encoding instead of one of the aliases Java accepts, we could increase
performance a little simply because the cache was working as intended.
Before we made that above adjustment in encoding names, threads in our
server simply blocked immediately on that monitor. After the fix, it
would take each thread a bit longer to block, presumably because any given
thread sometimes was able to use its cached converter, thus reducing
contention, but after several minutes, we still reach the situation described
earlier, 90% blocked or more. That is likely due to the fact that our
threads must regularly manipulate Strings in more than one encoding.
This is clearly the same issue described in Bug #4370850, where I
earlier posted a comment, but I am submitting this bug report to make it
clear that this has to be considered a bug, not a feature request, as
there is no workaround and the use of Strings is central and unavoidable in
nearly all Java systems.
(Review ID: 114649)