Java String.substring方法潜在的内存泄漏?

我正在浏览String类API,看起来像substring方法导致潜在的内存泄漏,因为它与原始String共享相同的字符数组。

如果原始字符串很大,则子字符串返回的小字符串可以防止Java中的原始字符串(由大数组备份)进行垃圾收集。

任何想法或我读错了API。

如果您获取相当大的字符串的子字符串而不进行复制(通常通过String(String)构造函数),则可能存在内存泄漏。

请注意,自Java 7u6以来,这已经发生了变化。 请参见http://bugs.sun.com/view_bug.do?bug_id=4513622 。

围绕实现flyweight模式的String对象的原始假设不再被视为有效。

有关详细信息,请参阅此答案 。

  1. 在Java 7u6之前就是这种情况 – 您通常会通过以下方式处理该问题:

     String sub = new String(s.substring(...)); // create a new string 

    这有效地消除了依赖性,原始字符串现在可用于GC。 这是使用字符串构造函数的唯一场景之一。

  2. 从Java 7u6开始 ,创建了一个新的String,并且不再存在内存问题。

在Java 7中,String的subString被修改为:

 /** * Returns a new string that is a substring of this string. The * substring begins with the character at the specified index and * extends to the end of this string. 

* Examples: *

 * "unhappy".substring(2) returns "happy" * "Harbison".substring(3) returns "bison" * "emptiness".substring(9) returns "" (an empty string) * 

* * @param beginIndex the beginning index, inclusive. * @return the specified substring. * @exception IndexOutOfBoundsException if * beginIndex is negative or larger than the * length of this String object. */ public String substring(int beginIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } int subLen = value.length - beginIndex; if (subLen < 0) { throw new StringIndexOutOfBoundsException(subLen); } return (beginIndex == 0) ? this : new String(value, beginIndex, subLen); }

因此,每次使用beginIndex不等于0的subString时,我们都有新的String Object。