Método de cadena de Java.substring pérdida de memoria potencial?

Estaba revisando la API de la clase String y parece que hay una posible pérdida de memoria causada por el método de subcadena, ya que comparte la misma matriz de caracteres que la cadena original.

Si la cadena original es enorme, una cadena pequeña devuelta por una subcadena puede evitar la cadena original (respaldada por una matriz grande) de la recolección de basura en Java.

Alguna idea o he leído la API equivocada.

Existe la posibilidad de una pérdida de memoria, si toma una subcadena de una cadena considerable y no realiza una copia (generalmente a través del constructor String(String) ).

Tenga en cuenta que esto ha cambiado desde Java 7u6 . Ver http://bugs.sun.com/view_bug.do?bug_id=4513622 .

Las suposiciones originales en torno al objeto String que implementa un patrón flyweight ya no se consideran válidas.

Vea esta respuesta para más información.

  1. Fue el caso hasta Java 7u6: generalmente abordarías el problema haciendo lo siguiente:

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

    Eso efectivamente elimina la dependencia y la cadena original ahora está disponible para GC. Este es, por cierto, uno de los únicos escenarios en los que el uso del constructor de cadenas tiene sentido.

  2. Desde Java 7u6 , se crea una nueva Cadena y ya no hay problemas de memoria.

En Java 7, el subString de String se modifica a:

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

Por lo tanto, cada vez que haga subString con beginIndex NOT equal to 0, tenemos un nuevo String Object.