Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6767959
Votes 0
Synopsis Catalog resolver transient memory usage high
Category jaxp:other
Reported Against
Release Fixed 6u11-rev(b06), 6u14(b02) (Bug ID:2173285) , 1.4(Bug ID:2173507)
State 10-Fix Delivered, bug
Priority: 2-High
Related Bugs
Submit Date 05-NOV-2008
Description
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. customer .xml.internal.resolver.Catalog.resolveSystem
 4.4% - 7,735 kB - 56,164 alloc.
com.sun.org. customer .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. customer .xml.internal.resolver.Catalog.resolvePublic
 3.1% - 5,507 kB - 44,460 alloc.
com.sun.org. customer .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();
        }
Posted Date : 2008-11-05 18:18:13.0
Work Around
N/A
Evaluation
used StringBuffer instead of string.
Posted Date : 2008-12-19 18:00:33.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang