Olá novamente! Abrimos o próximo conjunto no agora nono grupo
, o Java Developer Group (e o décimo grupo nos planos, de repente, é em 31 de dezembro) e preparamos materiais interessantes e
uma lição aberta para você.
Então vamos lá.
Deseja reduzir a quantidade de memória usada pelo seu aplicativo Java? Veja como você pode melhorar o desempenho com as cadeias compactas disponíveis no Java 9.
Uma das melhorias de desempenho introduzidas na JVM (Oracle HotSpot, para ser mais preciso), como parte do Java SE 9, acabou por ser sequências compactas. Sua tarefa é reduzir o tamanho dos objetos String, o que permite reduzir a quantidade total (área ocupada) de memória consumida pelo aplicativo. Como resultado, isso pode reduzir a quantidade de tempo gasto na coleta de lixo.

A função é baseada na observação de que muitos objetos String não precisam de 2 bytes para codificar cada caractere, já que a maioria dos aplicativos usa apenas caracteres Latin-1. Portanto, em vez disso:
private final char value[];
Em
java.lang.String
agora tem isso:
private final byte[] value; private final byte coder;
Em outras palavras, essa função substitui o valor na matriz
char
(onde cada elemento usa 2 bytes) por uma matriz de bytes com um byte adicional para determinar a codificação (Latin-1 ou UTF-16). Isso significa que, na maioria dos aplicativos que usam apenas caracteres latino-1, apenas metade da pilha será usada. O usuário não notará as diferenças, mas as APIs relacionadas, como
StringBuilder
, tirarão vantagem automaticamente disso.
Para mostrar essa alteração em termos do tamanho do objeto String, usarei o Java Object Layout, um utilitário simples para visualizar a estrutura do objeto no heap. Deste ponto de vista, estamos interessados na área de cobertura da matriz (armazenada na variável de valor acima), e não apenas em uma referência (uma referência de matriz de bytes, como uma referência de matriz de caracteres, usa 4 bytes). O código abaixo exibe as informações usando o JOL
GraphLayout
:
public class JOLSample { public static void main(String[] args) { System.out.println(GraphLayout.parseInstance("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz").toFootprint()); } }
) ToFootprint ()); public class JOLSample { public static void main(String[] args) { System.out.println(GraphLayout.parseInstance("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz").toFootprint()); } }
A execução do código acima no Java 8 e depois no Java 9 mostra a diferença:
$java -version java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode) $java -cp lib\jol-cli-0.9-full.jar;. test.JOLSample java.lang.String@4554617cd footprint: COUNT AVG SUM DESCRIPTION 1 432 432 [C 1 24 24 java.lang.String 2 456 (total) ... $java -version java version "9" Java(TM) SE Runtime Environment (build 9+181) Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode) $java -cp lib\jol-cli-0.9-full.jar;. test.JOLSample java.lang.String@73035e27d footprint: COUNT AVG SUM DESCRIPTION 1 224 224 [B 1 24 24 java.lang.String 2 248 (total)
Ignorando o tamanho de 24 bytes dos componentes internos de java.lang.String (cabeçalho mais links), vemos que, devido à sua compacidade, o tamanho quase caiu pela metade.
Se substituirmos a linha acima por outra usando caracteres UTF-16, por exemplo \ u0780, e reiniciarmos o código acima, o Java 8 e o Java 9 mostrarão o mesmo espaço, pois a compactação não será mais usada.
Você pode desativar esta função passando o
-XX:-CompactStrings
para o comando
java
.
Como sempre, estamos aguardando seus comentários e perguntas aqui, além de convidá-lo para
uma aula aberta .