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

Catalog resolver transient memory usage high

XMLWordPrintable

    • b06
    • sparc
    • solaris_2.5.1

        During memory analysis, we found high transient memory usage (8MB)
        in the Catalog.normalizeURI usage of StringBuilder.append:

        4.5% - 7,841 kB - 57,052 alloc.
        com.sun.org.apache.xml.internal.resolver.Catalog.resolveSystem
         4.4% - 7,735 kB - 56,164 alloc.
        com.sun.org.apache.xml.internal.resolver.Catalog.normalizeURI
          1.9% - 3,253 kB - 7,486 alloc. java.lang.StringBuilder.append(char)
          1.0% - 1,765 kB - 8,670 alloc.
        java.lang.StringBuilder.append(java.lang.String)
        3.2% - 5,626 kB - 45,912 alloc.
        com.sun.org.apache.xml.internal.resolver.Catalog.resolvePublic
         3.1% - 5,507 kB - 44,460 alloc.
        com.sun.org.apache.xml.internal.resolver.Catalog.normalizeURI
          1.3% - 2,255 kB - 5,738 alloc. java.lang.StringBuilder.append(char)
          0.7% - 1,245 kB - 6,794 alloc.
        java.lang.StringBuilder.append(java.lang.String)

        The culprit is the following for loop that creates new StringBuilder instances with 0 size, so that each call to append creates a new StringBuilder instance, leaving the
        old one on the heap, hence the high transient memory usage.


                for(int count = 0; count < bytes.length; count++)
                {
                    int ch = bytes[count] & 0xff;
                    if(ch <= 32 || ch > 127 || ch == 34 || ch == 60 || ch == 62 || ch
        == 92 || ch == 94 || ch == 96 || ch == 123 || ch == 124 || ch == 125 || ch ==
        127)
                        newRef = (new
        StringBuilder()).append(newRef).append(encodedByte(ch)).toString();
                    else
                        newRef = (new
        StringBuilder()).append(newRef).append((char)bytes[count]).toString();
                }

        Recommendation:
        1. create StringBuilder with estimated capacity before the for loop


                StringBuilder sb = new StringBuilder(bytes.length);

                for(int count = 0; count < bytes.length; count++)
                {
                    int ch = bytes[count] & 0xff;
                    if(ch <= 32 || ch > 127 || ch == 34 || ch == 60 || ch == 62 || ch
        == 92 || ch == 94 || ch == 96 || ch == 123 || ch == 124 || ch == 125 || ch ==
        127)
                        newRef =
        sb.append(newRef).append(encodedByte(ch)).toString();
                    else
                        newRef =
        sb.append(newRef).append((char)bytes[count]).toString();
                }

              asaha Abhijit Saha
              mbykov Misha Bykov (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: