El 19 de agosto, Oracle lanzó JDK 8u20. JDK 8u20 incluye muchas características nuevas, como actualizaciones del compilador Java, soporte para modificar los parámetros MinHeapFreeRatio y MaxHeapFreeRatio a través de API en tiempo de ejecución y nuevos documentos de guía de ajuste de GC. Sin embargo, entre las muchas características nuevas, la más esperada es la deduplicación de cadenas. Cómo reducir el uso de memoria siempre ha sido un tema eterno en las aplicaciones Java, a menudo se ve que el objeto String ocupa el 30% de la memoria de la aplicación. Es uno de los objetos más utilizados en Java. La nueva función de deduplicación de cadenas puede ayudar a reducir el uso de memoria de los objetos String en las aplicaciones. Actualmente, esta función solo está disponible para el recolector de basura G1 y no está habilitada de forma predeterminada.
Fabian Lange explica cómo se implementa la deduplicación de cadenas:
Copie el código de código de la siguiente manera:
El recolector de basura marcará la matriz de caracteres del objeto String cuando se acceda a él y guardará el valor hash de String y la referencia débil en una matriz. Cuando el recolector de basura encuentra otro objeto String con el mismo valor hash, compara los dos objetos carácter por carácter. Si coinciden exactamente, una Cadena se modificará para que apunte a la matriz de caracteres de la otra Cadena. Dado que ya no se hace referencia a la primera matriz de caracteres, se puede reciclar. El recolector de basura intentará reducir el costo de toda la operación. Por ejemplo, si se escanea un objeto String y no se encuentran duplicados, no se volverá a verificar en el próximo período de tiempo.
A continuación, Fabian Lange explicó el efecto mágico de la deduplicación de cadenas a través del código. Primero ejecute el siguiente código usando Java 8 Update 20 con los parámetros -Xmx256m -XX:+UseG1GC:
Copie el código de código de la siguiente manera:
clase pública muchas cadenas {
LinkedList final estático privado<String> LOTS_OF_STRINGS = new LinkedList<>();
public static void main (String [] args) lanza una excepción {
iteración = 0;
mientras (verdadero) {
para (int i = 0; i < 100; i++) {
para (int j = 0; j < 1000; j++) {
LOTS_OF_STRINGS.add(new String("Cadena " + j));
}
}
iteración++;
System.out.println("Iteración sobrevivida: " + iteración);
Hilo.dormir(100);
}
}
}
El código dejará de ejecutarse debido a la excepción OutOfMemoryError después de 30 bucles. Después de usar los parámetros -XX:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics para habilitar la función de deduplicación de cadenas, el programa puede ejecutarse durante un período de tiempo más largo. También puede obtener más información sobre los detalles de todo el proceso de deduplicación a través de los registros de JVM. Se pide a los lectores que lo prueben ellos mismos.
Finalmente, Fabian Lange también explicó la diferencia entre la deduplicación de cadenas y la residencia de cadenas. Son muy similares, excepto que la residencia de cadenas reutiliza toda la instancia de String, mientras que la deduplicación de cadenas solo apunta a la matriz de caracteres de String.
(Finaliza el texto completo)