United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-4637640 : Memory leak due to String.substring() implementation

Details
Type:
Bug
Submit Date:
2002-02-14
Status:
Closed
Updated Date:
2005-07-26
Project Name:
JDK
Resolved Date:
2002-02-14
Component:
core-libs
OS:
windows_nt
Sub-Component:
java.lang
CPU:
x86
Priority:
P4
Resolution:
Duplicate
Affected Versions:
1.4.0
Fixed Versions:

Related Reports
Duplicate:
Relates:

Sub Tasks

Description
Name: rmT116609			Date: 02/13/2002


java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

and also

java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
Classic VM (build 1.3.0, J2RE 1.3.0 IBM build co130-20010925 (JIT enabled: jitc)
)

DESCRIPTION OF THE PROBLEM :

String.substring() and StringBuffer.substring() attempt to improve performance (and reduce the memory footprint) by sharing the underlying char[] across various Strings.

However, a problem arises in the following scenerio:

1) Create a huge temporary StringBuffer
2) Extract short strings using substring() and place them in long-term storage (in a table of some sort)
3) Delete the StringBuffer, assuming it will be garbage-collected

However, due to implementation issues the huge StringBuffer will not be garbage collected so long as the substrings extracted from it live. This poses a problem and can potencially lead to huge memory leaks.

I don't necessarily have a solution, but I *did* want to point out this problem. This lead to a memory leak of 10MB/second on my sample app and I only managed to track down the problem by looking at the sources in String.java.

Upon forcing a String copy via getChars(), the memory leak disappeared and the huge buffer was being garabage collected properly.

The API should handle this problem better or at the very least provide extensive documentation on this topic.

This bug can be reproduced always.

Source:

class Test{

public static void main(String a[]) {

 String [] buffer = new String[10000];
 for (int i = 0; i < 10000; i++) 
 {
  buffer[i] = new String(new char[10000000]).substring(0, 1);
 }

}
}

The above is really bad coding, but it demonstrates what is happening. The above will keep references to all char[10000000] instances for as long as buffer[] lives.

CUSTOMER WORKAROUND :
Copy substrings manually; however this makes the code JVM-specific.
(Review ID: 139509) 
======================================================================

                                    

Comments



Hardware and Software, Engineered to Work Together