subString() no memory leak any more

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

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方法的实现:

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);
}

参考资料