Recolección de basura de literales de cadena

Estoy leyendo acerca de la recolección de basura y obtengo resultados de búsqueda confusos cuando busco colecciones literales de basura de String.

Necesito una aclaración sobre los siguientes puntos:

  1. Si una cadena se define como literal en el momento de la comstackción [por ejemplo: String str = "java" ], ¿se recolectará basura?

  2. Si usa el método interno [por ejemplo: String str = new String("java").intern() ] ¿se recolectará basura? También será tratado de manera diferente al literal de cadena en el punto 1.

  3. En algunos lugares, se menciona que los literales serán basura recolectada solo cuando se descargue la clase String . Tiene sentido porque no creo que String clase String nunca se descargue.

Si una cadena se define como literal en el momento de la comstackción [por ejemplo: String str = "java"; ] entonces será basura recogida?

Probablemente no. Los objetos de código contendrán una o más referencias a los objetos String que representan los literales. Por lo tanto, siempre que los objetos de código sean alcanzables, los objetos de String serán a.

Es posible que los objetos de código sean inalcanzables, pero solo si se cargan dinámicamente … y se destruye su cargador de clases.

Si utilizo el método interno [por ejemplo: String str = new String("java").intern() ] ¿se recolectará basura?

El objeto devuelto por la llamada intern será el mismo objeto que representa el literal de la cadena "java" . (El literal "java" se interna en el tiempo de carga de clase. Cuando interne el objeto String recién construido en su fragmento de código, buscará y devolverá la cadena "java" previamente intercalada).

Sin embargo, las cadenas internas que no son idénticas a los literales de cadena pueden ser recogidas como basura una vez que se vuelven inalcanzables. El espacio PermGen es basura recolectada en todas las JVM HotSpot recientes. (Antes de Java 8 … que deja PermGen por completo).

También será tratado de manera diferente al literal de cadena en el punto 1.

No … porque es el mismo objeto que el literal de la cadena.

Y, de hecho, una vez que comprenda lo que está sucediendo, es claro que los literales de cadena tampoco son tratados de manera especial. Es solo una aplicación de la regla de “alcanzabilidad” …

En algunos lugares, se menciona que los literales serán basura recolectada solo cuando se descargue la clase String . Tiene sentido porque no creo que la clase String nunca se descargue.

Tienes razón. No tiene sentido. Las fonts que dijeron que son incorrectas. (Sería útil si publicaras una URL para que podamos leer lo que dicen por nosotros mismos …)

En circunstancias normales, los literales de cadena y las clases se asignan a la generación permanente de la JVM (“PermGen”) y, por lo general, nunca se recostackrán. Las cadenas que están internados (por ejemplo, mystring.intern() ) se almacenan en un grupo de memoria propiedad de la clase String en permgen, y una vez fue el caso de que la interna agresiva podría causar una fuga de espacio porque el grupo de cadenas tenía una referencia a cada cadena, incluso si no existieran otras referencias. Al parecer, esto ya no es cierto, al menos a partir de JDK 1.6 (ver, por ejemplo, aquí ).

Para obtener más información sobre permgen, esta es una descripción decente del tema. (Nota: ese enlace va a un blog asociado a un producto. No tengo ninguna asociación con el blog, la empresa o el producto, pero la entrada del blog es útil y no tiene mucho que ver con el producto. )

  1. La cadena literal permanecerá en la memoria siempre que el progtwig esté en la memoria.
  2. str será basura recolectada, pero el literal del que se creó no lo hará.
  3. Eso tiene mucho sentido, ya que la clase de cadena se descarga cuando el progtwig está descargado.

intern() método intern() comprueba la disponibilidad del objeto en String pool. Si el objeto / literal está disponible, se devolverá su referencia. Si el literal no está allí en el grupo, entonces el objeto se carga en el área permanente (String pool) y luego se devolverá la referencia. Tenemos que usar el método intern() juiciosamente.