Otimizando o Desempenho de Aplicações Java

JavaBeginner
Pratique Agora

Introdução

Os parâmetros da JVM (Java Virtual Machine) são utilizados para configurar a Máquina Virtual Java, responsável por executar o bytecode Java. Ao configurar adequadamente os parâmetros da JVM, podemos melhorar o desempenho das aplicações Java. Neste laboratório, aprenderemos como definir alguns parâmetros da JVM comumente utilizados para otimizar o desempenho de aplicações Java.

Definindo a Memória Heap

A memória heap (heap memory) é a área de dados em tempo de execução na qual os objetos Java são alocados. Podemos definir o tamanho da memória heap com os parâmetros -Xmx e -Xms.

  • -Xmx<tamanho do heap>[unidade]: define o tamanho máximo do heap.
  • -Xms<tamanho do heap>[unidade]: define o tamanho inicial do heap.

Por exemplo, para definir o tamanho mínimo do heap para 512MB e o tamanho máximo do heap para 1GB, podemos usar o seguinte comando:

java -Xms512m -Xmx1g MyApp

Escolhendo os Garbage Collectors

A coleta de lixo (garbage collection) é o processo de liberar a memória ocupada por objetos que não estão mais sendo utilizados pela aplicação Java. A escolha do coletor de lixo pode ter um impacto significativo no desempenho da aplicação. A JVM fornece vários coletores de lixo, cada um com suas próprias forças e fraquezas.

  • -XX:+UseSerialGC: habilita o coletor de lixo serial, que utiliza uma única thread para a coleta de lixo.
  • -XX:+UseParallelGC: habilita o coletor de lixo paralelo, que utiliza múltiplas threads para a coleta de lixo.
  • -XX:+UseParNewGC: habilita o coletor de lixo concurrent-mark-sweep (CMS), que utiliza múltiplas threads para realizar a coleta de lixo concorrente.
  • -XX:+UseG1GC: habilita o coletor de lixo Garbage-first (G1), que é projetado para fornecer tempos de pausa consistentes e alta taxa de transferência (throughput).

Por exemplo, para habilitar o coletor de lixo paralelo, podemos usar o seguinte comando:

java -XX:+UseParallelGC MyApp

Registrando as Atividades do Garbage Collection

O registro (logging) da coleta de lixo nos permite monitorar o desempenho do coletor de lixo e ajustar os parâmetros do coletor de lixo com base nos requisitos da aplicação. Podemos usar os seguintes parâmetros para habilitar o registro da coleta de lixo:

  • -XX:+UseGCLogFileRotation: habilita a rotação de logs para os logs da coleta de lixo.
  • -XX:NumberOfGCLogFiles=<número de arquivos de log>: limita o número de arquivos de log para os logs da coleta de lixo.
  • -XX:GCLogFileSize=<tamanho do arquivo><unidade>: especifica o limite de tamanho para os logs da coleta de lixo.
  • -Xloggc:[caminho para o arquivo gc.log]: especifica o caminho para os logs da coleta de lixo.

Por exemplo, para habilitar o registro da coleta de lixo e definir o caminho do arquivo de log para /path/to/gc.log, podemos usar o seguinte comando:

java -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M -Xloggc:/path/to/gc.log MyApp

Tratamento de Erros de Falta de Memória (Out of Memory)

Quando a JVM fica sem memória, ela lança um Erro de Falta de Memória (Out Of Memory Error). Podemos usar os seguintes parâmetros da JVM para tratar este erro:

  • -XX:+HeapDumpOnOutOfMemoryError: quando o Erro de Falta de Memória ocorre, a JVM escreverá um heap dump no disco.
  • -XX:HeapDumpPath=<caminho para o arquivo heap dump>: especifica o caminho para o arquivo heap dump.
  • -XX:OnOutOfMemoryError=<comando>: quando o Erro de Falta de Memória ocorre, a JVM executará o comando especificado.
  • -XX:+UseGCOverheadLimit: a JVM usa esta opção para definir um limite na quantidade de tempo gasto na coleta de lixo.

Por exemplo, para configurar a JVM para escrever um heap dump no arquivo /path/to/heapdump.hprof quando o Erro de Falta de Memória ocorre, podemos usar o seguinte comando:

java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/heapdump.hprof MyApp

Utilizando a JVM de 64 bits

Podemos usar o parâmetro -d para selecionar a JVM de 32 bits ou 64 bits. Por exemplo, para usar a JVM de 64 bits, podemos usar o seguinte comando:

java -d64 MyApp

Compilação e Execução de Aplicações Java com Parâmetros da JVM

Vamos usar o programa HelloWorld.java para compilar e executar a aplicação Java com os parâmetros da JVM que aprendemos nos passos anteriores.

cd ~/project
touch HelloWorld.java
touch HelloWorld.java

Insira o seguinte código:

class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}

Salve o arquivo e saia. Agora, vamos compilar e executar o código com o parâmetro -Xmx:

javac HelloWorld.java
java -Xmx512m HelloWorld

Isso define o tamanho máximo do heap para 512MB. Devemos ver a saída:

Hello, World!

Compilação e Execução de Aplicações Java com Garbage Collectors

Agora, vamos compilar e executar a aplicação Java com o coletor de lixo (garbage collector) paralelo:

java -XX:+UseParallelGC HelloWorld

Devemos ver a saída:

Hello, World!

Compilação e Execução de Aplicações Java com Logging de Garbage Collection

Agora, vamos compilar e executar a aplicação Java com o logging de garbage collection habilitado:

java -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=10M -Xloggc:/path/to/gc.log HelloWorld

Isso define o caminho do arquivo de log para /path/to/gc.log.

Compilação e Execução de Aplicações Java com Outros Parâmetros Frequentemente Utilizados

Agora, vamos compilar e executar a aplicação Java com os parâmetros -XX:+UseStringDeduplication e -XX:MaxHeapFreeRatio:

java -XX:+UseStringDeduplication -XX:MaxHeapFreeRatio=70 HelloWorld

Isso habilita a deduplicação de strings e define a proporção máxima de espaço livre no heap (heap space) após a coleta de lixo para 70%.

Resumo

Neste laboratório, aprendemos como definir vários parâmetros da JVM para otimizar o desempenho de aplicações Java. Aprendemos como definir o tamanho da memória do heap (heap memory), escolher coletores de lixo (garbage collectors), habilitar o logging de garbage collection, lidar com erros Out Of Memory, usar a JVM de 64 bits e definir alguns outros parâmetros frequentemente usados. Também aprendemos como compilar e executar uma aplicação Java com parâmetros da JVM.