Em 19 de agosto, a Oracle lançou o JDK 8u20. O JDK 8u20 inclui muitos novos recursos, como atualizações do compilador Java, suporte para modificação de parâmetros MinHeapFreeRatio e MaxHeapFreeRatio por meio de APIs em tempo de execução e novos documentos de guia de ajuste de GC. No entanto, entre os muitos novos recursos, o mais esperado é a desduplicação de strings. Como reduzir o uso de memória sempre foi um tópico eterno em aplicativos Java, muitas vezes é visto que o objeto String ocupa 30% da memória do aplicativo. O novo recurso de desduplicação de string pode ajudar a reduzir o consumo de memória de objetos String em aplicativos. Atualmente, esse recurso está disponível apenas para o coletor de lixo G1 e não está habilitado por padrão.
Fabian Lange explica como a desduplicação de strings é implementada:
Copie o código do código da seguinte forma:
O coletor de lixo marcará a matriz de caracteres do objeto String quando for acessado e salvará o valor hash da String e a referência fraca em uma matriz. Quando o coletor de lixo encontra outro objeto String com o mesmo valor de hash, ele compara os dois objetos caractere por caractere. Se corresponderem exatamente, uma String será modificada para apontar para a matriz de caracteres da outra String. Como a primeira matriz de caracteres não é mais referenciada, ela pode ser reciclada. O coletor de lixo tentará reduzir o custo de toda a operação. Por exemplo, se um objeto String for verificado e nenhuma duplicata for encontrada, ele não será verificado novamente no próximo período.
A seguir, Fabian Lange explicou o efeito mágico da desduplicação de strings por meio de código. Primeiro execute o seguinte código usando Java 8 Update 20 com parâmetros -Xmx256m -XX:+UseG1GC:
Copie o código do código da seguinte forma:
classe pública LotesOfStrings {
private static final LinkedList<String> LOTS_OF_STRINGS = new LinkedList<>();
public static void main(String[] args) lança exceção {
iteração interna = 0;
enquanto (verdadeiro) {
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 1000; j++) {
LOTS_OF_STRINGS.add(new String("String " + j));
}
}
iteração++;
System.out.println("Iteração sobrevivente: " + iteração);
Thread.sleep(100);
}
}
}
O código terminará a execução devido à exceção OutOfMemoryError após 30 loops. Depois de usar os parâmetros -XX:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics para ativar o recurso de desduplicação de string, o programa pode ser executado por um período de tempo mais longo. Você também pode aprender mais sobre os detalhes de todo o processo de desduplicação por meio dos logs da JVM. Os leitores são convidados a testá-lo eles mesmos.
Por fim, Fabian Lange também explicou a diferença entre desduplicação de string e residência de string. Eles são muito semelhantes, exceto que a residência de string reutiliza toda a instância de String, enquanto a desduplicação de string tem como alvo apenas a matriz de caracteres de String.
(O texto completo termina)