subString() no memory leak any more

《Java程序性能优化》第三章Java程序优化首先讲的是字符串的特性及其相应的优化方法。3.1.2小节subString()方法的内存泄漏深入JDK的subString方法实现,并指出了大字符串对象可能存在的内存泄漏。我尝试把书中的程序段输入并运行,但结果并没有产生内存泄漏,原来情况有变。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class TestSubString {
public static void main(String[] args) {
List<String> handler = new ArrayList<String>();
for (int i = 0; i < 10000 ; i++) {
HugeStr h = new HugeStr();
// ImprovedHugeStr h = new ImprovedHugeStr();
handler.add(h.getSubString(1, 5));
}
}
static class HugeStr {
private String str = new String(new char[100000]);
public String getSubString(int begin, int end){
return str.substring(begin, end);
}
}
static class ImprovedHugeStr{
private String str = new String(new char[100000]);
public String getSubString(int begin, int end){
return new String(str.substring(begin, end));
}
}
}

参考网上的几个回答之后,原来在JDK7u6之后,这个问题已经解掉了,所以在新的JDK版本中就不用担心subString的内存泄漏了。

附JDK7(build 1.7.0_72-b14)中String类subString方法的实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public String substring(int beginIndex, int endIndex) {
if (beginIndex < 0) {
throw new StringIndexOutOfBoundsException(beginIndex);
}
if (endIndex > value.length) {
throw new StringIndexOutOfBoundsException(endIndex);
}
int subLen = endIndex - beginIndex;
if (subLen < 0) {
throw new StringIndexOutOfBoundsException(subLen);
}
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
}

参考资料