java string permgen string-interning

¿Vida real, ejemplo práctico de uso de String.intern() en Java?



permgen string-interning (5)

Los ejemplos en los que la pasantía será beneficiosa incluyen un gran número de cadenas donde:

  • es probable que las cuerdas sobrevivan a múltiples ciclos de GC, y
  • es probable que haya varias copias de un gran porcentaje de las cadenas.

Los ejemplos típicos implican dividir / analizar un texto en símbolos (palabras, identificadores, URI) y luego adjuntar esos símbolos a estructuras de datos de larga duración. El procesamiento de XML, la compilación del lenguaje de programación y las tiendas RDF / OWL triples vienen a la mente como aplicaciones en las que la práctica puede ser beneficiosa.

Pero la internación no está exenta de problemas, especialmente si resulta que las suposiciones anteriores no son correctas:

  • la estructura de datos de la agrupación utilizada para mantener las cadenas internadas ocupa espacio adicional,
  • interning toma tiempo, y
  • interning no impide la creación de la cadena duplicada en primer lugar.

Finalmente, la internación aumenta potencialmente los gastos generales de GC al aumentar la cantidad de objetos que se deben rastrear y copiar, y al aumentar la cantidad de referencias débiles que deben tratarse. Este aumento en los gastos generales debe compensarse con la disminución en los gastos generales de GC que resulta de una práctica efectiva.

He visto muchos ejemplos primitivos que describen cómo funciona String intern () ''ing, pero todavía tengo que ver un caso de uso de la vida real que se beneficiaría de ello.

La única situación que puedo imaginar es tener un servicio web que reciba una cantidad considerable de solicitudes, cada una de ellas de naturaleza muy similar debido a un esquema rígido. Al ingresar los nombres de los campos de solicitud en este caso, el consumo de memoria se puede reducir significativamente.

¿Puede alguien proporcionar un ejemplo de uso de intern () en un entorno de producción con gran éxito? Tal vez un ejemplo de ello en una oferta de código abierto popular?

Edición: Me refiero a las prácticas manuales, no a las prácticas garantizadas de literales de cadenas, etc.


No es una respuesta completa pero es un alimento adicional para el pensamiento (se encuentra aquí ):

Por lo tanto, el beneficio principal en este caso es que usar el operador == para cadenas internalizadas es mucho más rápido que usar el método equals() [para cadenas no internalizadas]. Por lo tanto, use el método intern() si va a comparar cadenas más de una o tres veces.


Nunca, nunca , use el interno en los datos proporcionados por el usuario, ya que eso puede causar ataques de denegación de servicio (ya que las cadenas intern () nunca se liberan). Puede hacer la validación de las cadenas proporcionadas por el usuario, pero nuevamente ha hecho la mayor parte del trabajo necesario para intern ().


Teníamos un sistema de producción que procesa literalmente millones de datos a la vez, muchos de los cuales tienen campos de cadena. Deberíamos haber estado internando cadenas, pero había un error que significaba que no lo estábamos. Al corregir el error, evitamos tener que realizar una actualización del servidor muy costosa (al menos 6 cifras, posiblemente 7).


La pasantía puede ser muy beneficiosa si tiene N cadenas que solo pueden tomar K valores diferentes, donde N supera con creces a K Ahora, en lugar de almacenar N cadenas en la memoria, solo almacenará hasta K

Por ejemplo, puede tener un tipo de ID que consta de 5 dígitos. Por lo tanto, solo puede haber 10^5 valores diferentes. Supongamos que ahora está analizando un documento grande que tiene muchas referencias / referencias cruzadas a valores de ID . Digamos que este documento tiene un total de 10^9 referencias (obviamente, algunas referencias se repiten en otras partes de los documentos).

Entonces N = 10^9 y K = 10^5 en este caso. Si no está internando las cadenas, almacenará 10^9 cadenas en la memoria, donde muchas de esas cadenas son equals (según el principio del casillero ). Si realiza intern() la cadena de ID que obtiene cuando analiza el documento y no guarda ninguna referencia a las cadenas no insertadas que leyó en el documento (para que puedan ser recolectadas como basura), entonces nunca necesitará almacenar más de 10^5 cadenas en la memoria.