Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4370850

java.lang.String always creates new converters creating a race condition



    • Type: Bug
    • Status: Resolved
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: 1.3.0
    • Fix Version/s: 1.3.1_07
    • Component/s: core-libs
    • Labels:
    • Subcomponent:
    • Resolved In Build:
    • CPU:
      generic, x86
    • OS:
      generic, linux


      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
              at sun.io.Converters.newDefaultConverter(Converters.java:197)
              at sun.io.ByteToCharConverter.getDefault(ByteToCharConverter.java:55)
              at java.lang.String.<init>(String.java:451)

      "wap-servlet-4" prio=1 tid=0x81920f0 nid=0x6b54 waiting for monitor entry
              at sun.io.Converters.newConverter(Converters.java:123)
              at sun.io.CharToByteConverter.getConverter(CharToByteConverter.java:67)
              at java.lang.String.getCTBConverter(String.java:151)
              at java.lang.String.getBytes(String.java:665)
      (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
              at sun.io.Converters.newConverter(Converters.java:137)
              at sun.io.ByteToCharConverter.getConverter(ByteToCharConverter.java:67)
              at java.lang.String.getBTCConverter(String.java:124)
              at java.lang.String.<init>(String.java:401)
              at java.lang.String.<init>(String.java:422)

      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)




            mr Mark Reinhold
            skonchad Sandeep Konchady
            0 Vote for this issue
            0 Start watching this issue