Gerenciamento de Memória Java

Danilo Morais
3 min readJun 16, 2020

--

Antes de mais nada, vamos falar um pouco sobre a linguagem de programação orientada a objetos Java.

Foi desenvolvida na década de 90 por uma equipe de programadores chefiada por James Gosling (conhecido como o pai do Java) , na empresa Sun Microsystems e em 2008 foi adquirida pela Oracle Corporation.

A tecnologia é vastamente utilizada no desenvolvimento de sistemas de servidores e desenvolvimento de aplicações no geral, mais de 90% das empresas selecionadas pela Fortune 500 dependem de Java para operar seus produtos e serviços. Apesar de sua idade, a linguagem é estável e não vai se aposentar tão cedo. Isso faz do Java uma das mais desejáveis entre os programadores em 2020, segundo o IEEE.

A linguagem Java é compilada para um bytecode, que é interpretada pelas Máquinas Virtuais Java (JVMs). É essa característica que faz com que os programas Java sejam independentes de plataforma, executando em qualquer sistema que possua uma JVM.

Bom, agora que você já sabe o que é o Java e uma JVM, vamos falar um pouco sobre o funcionamento e gerenciamento de memória na JVM.

Memória na JVM

Internamente, a JVM mantém uma área de memória dividida em duas partes: Heap e “Não-Heap”, onde todos os objetos criados durante a execução da aplicação e metadados das classes são gerados.

Estrutura de Memória Heap até o Java 7

Estrutura de Memória Heap a partir do Java 8

Como visto acima, podemos dividir a Memória Heap em três partes:

1. Young Generation (Geração Jovem)

A Geração Jovem é dividida em 3 espaços:

Eden Space e Survivor Space que obtém os espaços Survivor 0 e Survivor 1.

Toda a criação de objetos será armazenada no Eden Space, com isso, sempre que a JVM não consegue alocar espaço para um novo objeto o GC (Garbage Collector) excluirá todos os objetos não utilizados e não referenciados, onde esse mecanismo será chamado de GC Minor.

O GC Minor moverá todos os objetos sobreviventes para o Survivor 0, quando o Survivor 0 estiver cheio, os próximos objetos serão direcionados para o Survivor 1.

Os objetos que sobreviverem na Geração Jovem, serão movidos para Geração Antiga.

2. Old Generation (Geração Antiga)

Quando a Geração Antiga é preenchida com objetos, o GC Major ou também conhecido como “Full GC” é acionado.

Muitos Full GCs são acionados por GCs Minor, onde ocorre a limpeza de toda a Heap, com isso, vemos em diversos casos erros de timeout onde o tempo de limpeza do GC se torna elevado.

3. Permanent Generation/ Metaspace

Permanent Generation (Geração Permanente)

A Geração Permanente (presente até o Java 7), é considerada não-heap e é onde consiste na alocação de todos os métodos estáticos, variáveis primitivas e referências aos objetos estáticos.

Além disso, ele contém dados sobre bytecode, nomes e informações JIT. Antes do Java 7, o String Pool também fazia parte dessa memória.

Metaspace

Este é um novo espaço de memória a partir do Java 8, substituindo o espaço Permanent Gerenation que vimos acima. A vantagem do Metasspace é que o GC será acionado automaticamente para remover as classes mortas quando o uso de metadados da classe atinge seu tamanho máximo de metasspace.

Com essa melhoria, a JVM reduz a chance de obter o erro OutOfMemory.

Ah, se você está gostando dos nossos conteúdos, não esqueça de deixar o seu Like👍 e compartilhar com seus amigos.

Siga também o nosso canal no Youtube, onde falamos sobre dicas e melhores práticas de testes de Performance 🚀🧨😁

--

--

Danilo Morais

Senior System Performance Engineer | Site Reliability Engineering (SRE)