O ARMS Application Monitoring coleta métricas de memória da JVM para ajudar você a identificar vazamentos de memória, ajustar o garbage collection e dimensionar corretamente as alocações de heap e non-heap. Este tópico explica as áreas de memória que o ARMS monitora, como os dados são coletados e como solucionar problemas comuns de memória.
O agente do ARMS coleta dados de memória por meio do MemoryMXBean no Java Development Kit (JDK). Devido às limitações do MemoryMXBean, o ARMS não consegue monitorar todas as áreas de memória de um processo Java — as pilhas de threads da VM e a memória da Java Native Interface (JNI) estão excluídas. Para obter mais detalhes, consulte Interface MemoryMXBean.
Layout de memória do processo Java
O diagrama a seguir mostra as principais áreas de memória de um processo Java.
Este diagrama abrange apenas as principais áreas de memória. A estrutura real de memória da JVM é mais complexa.
Memória heap
O heap é a área de memória principal onde a JVM aloca objetos e executa o garbage collection (GC). O ARMS relata o uso do heap por meio do MemoryMXBean, mas o máximo relatado pode ser ligeiramente menor que o valor definido via -Xmx, dependendo do coletor de lixo em uso.
Por que o máximo relatado difere do -Xmx
O MemoryMXBean exclui as áreas de sobrevivência From Space e To Space do cálculo do heap. Isso causa uma discrepância para determinados coletores:
|
Coletor de lixo |
**Máximo relatado vs. |
|
Garbage-First (G1) Garbage Collector |
Corresponde ao |
|
Parallel Garbage Collector (ParallelGC) |
Ligeiramente abaixo do |
|
Concurrent Mark Sweep (CMS) Collector |
Ligeiramente abaixo do |
|
Serial Garbage Collector |
Ligeiramente abaixo do |
Exemplo: Com -XX:+UseParallelGC -Xms4096m -Xmx4096m, o ARMS relata um máximo de aproximadamente 3,8 GB em vez de 4 GB.

Memória non-heap
A memória non-heap relatada pelo ARMS é a soma de três áreas:
Non-heap memory = Metaspace + Compressed class space + Code cache
As pilhas de threads da VM e a memória JNI não estão incluídas no total de non-heap porque o MemoryMXBean não as rastreia.
Metaspace
Armazena metadados de classes — estruturas de classes, métodos e campos. O uso geralmente permanece estável após a inicialização da aplicação.
|
Parâmetro da JVM |
Finalidade |
|
|
Tamanho inicial do metaspace (JDK 8+) |
|
|
Tamanho máximo do metaspace (JDK 8+) |
Compressed class space
Armazena metadados de classes carregadas em formato compactado. Ao limitar o tamanho dos ponteiros, o compressed class space reduz o consumo de memória das aplicações Java. O tamanho padrão no JDK 11 é de 1 GB.
|
Parâmetro da JVM |
Finalidade |
|
|
Defina o tamanho do compressed class space |
Code cache
Armazena código nativo gerado pela JVM, incluindo loops do interpretador, stubs JNI, métodos compilados just-in-time (JIT) e métodos Java. A saída do JIT responde pela maior parte do uso do code cache.
|
Parâmetro da JVM |
Finalidade |
|
|
Tamanho inicial do code cache |
|
|
Tamanho máximo do code cache |
Direct buffer
Os direct buffers alocam memória no sistema operacional, e não no heap da JVM. Como evitam a cópia entre a memória da JVM e a do sistema operacional, oferecem desempenho de I/O mais rápido e processam grandes volumes de dados com eficiência. No entanto, operações intensivas de I/O aumentam proporcionalmente o consumo de memória do direct buffer.
Solucionar vazamentos de memória
Vazamentos de memória heap
Se a memória heap crescer continuamente ao longo do tempo, pode haver um vazamento. O ARMS oferece dois recursos para análise de vazamentos de memória heap:
Memory snapshot — Capture um snapshot do heap para inspecionar a alocação de objetos.
Continuous profiling — Rastreie alocações ao longo do tempo para identificar a source do vazamento.
Comece verificando o gráfico de memória heap da JVM no Application Monitoring. Se o heap utilizado apresentar tendência de alta em vários ciclos de GC, capture um snapshot de memória ou ative o continuous profiling.
Vazamentos de memória non-heap
Se a memória heap estiver estável, mas a memória total do processo continuar crescendo, é provável que haja um vazamento de non-heap. O ARMS não analisa a memória non-heap diretamente. Utilize a ferramenta Native Memory Tracking (NMT), fornecida pelo JDK, para monitorar alocações de memória non-heap.
Para obter mais detalhes, consulte Native Memory Tracking na documentação da Oracle.
O NMT exige conhecimento técnico e adiciona uma sobrecarga de desempenho de 5% a 10%. Avalie o impacto antes de ativá-lo em produção.
Perguntas frequentes
Por que a memória no Application Monitoring difere da saída do top?
O Application Monitoring coleta dados por meio do Java Management Extensions (JMX), que cobre apenas as áreas de heap e non-heap gerenciadas pela JVM. O Resident Memory Size em KiB (RES) relatado pelo top inclui memória adicional — pilhas de threads da VM, pilhas de threads locais e alocações fora da JVM — que o JMX não rastreia.
Por que a memória no Application Monitoring difere do Managed Service for Prometheus ou do Managed Service for Grafana?
Os dois sistemas usam fontes de dados diferentes. O Application Monitoring lê métricas JMX de dentro da JVM. Já o Managed Service for Grafana consulta métricas no nível do contêiner por meio da Prometheus Query Language (PromQL) — geralmente container_memory_working_set_bytes, que representa a soma do Resident Set Size (RSS) e do cache ativo dos cgroups de memória. Esse escopo é mais amplo que o do JMX.
Um pod reinicia devido ao out-of-memory (OOM) killer. Como solucionar problemas com o Application Monitoring?
O Application Monitoring ajuda a solucionar problemas de planejamento de capacidade de memória heap e direct buffer, mas não captura detalhes completos de RSS do processo. Para investigações de OOM killer, utilize o ecossistema de monitoramento do Prometheus no Kubernetes para rastrear a memória no nível do contêiner.
Verifique dois pontos:
Outros processos no pod — Verifique se o pod executa um único processo Java. Processos adicionais de sidecar ou auxiliares podem consumir memória fora do monitoramento da JVM.
Vazamentos fora da JVM — Bibliotecas como glibc podem causar vazamentos de memória nativa invisíveis ao JMX. Use o NMT ou ferramentas no nível do sistema operacional para investigar.