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
对象的原始假设不再被视为有效。
有关详细信息,请参阅此答案 。
-
在Java 7u6之前就是这种情况 – 您通常会通过以下方式处理该问题:
String sub = new String(s.substring(...)); // create a new string
这有效地消除了依赖性,原始字符串现在可用于GC。 这是使用字符串构造函数的唯一场景之一。
-
从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 thisString
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。