Problemas de reinicialização do aplicativo causados por problemas de memória insuficiente
Observação
Os planos Básico, Standard e Enterprise serão preteridos a partir de meados de março de 2025, com um período de desativação de 3 anos. Recomendamos a transição para os Aplicativos de Contêiner do Azure. Para mais informações, confira o anúncio de desativação dos Aplicativos Spring do Azure.
O plano Standard de consumo e dedicado será preterido a partir de 30 de setembro de 2024, com um desligamento completo após seis meses. Recomendamos a transição para os Aplicativos de Contêiner do Azure. Para mais informações, confira Migrar o plano Standard de consumo e dedicado dos Aplicativos Spring do Azure para os Aplicativos de Contêiner do Azure.
Este artigo se aplica ao: ✔️ nível Básico/Standard ✔️ nível Enterprise
Este artigo descreve os problemas de OOM (memória insuficiente) para aplicativos Java nos Aplicativos Spring do Azure.
Tipos de problemas de memória insuficiente
Há dois tipos de problemas de memória insuficiente: OOM do contêiner e OOM da JVM.
O OOM do contêiner, também chamado de OOM do sistema, ocorre quando a memória disponível do aplicativo esgota. O problema do OOM do contêiner causa eventos de reinicialização do aplicativo, que são relatados na seção Resource Health do portal do Azure. Normalmente, o OOM do contêiner é causado por configurações incorretas do tamanho da memória.
O OOM da JVM ocorre quando a quantidade de memória usada atinge o tamanho máximo definido nas opções da JVM. O OOM da JVM não fará com que um aplicativo seja reiniciado. Normalmente, o OOM da JVM resulta de um código incorreto, que pode ser encontrado procurando as exceções
java.lang.OutOfMemoryError
no log do aplicativo. O OOM da JVM tem um efeito negativo nas ferramentas de Criação de Perfil do Java e aplicativo, como o Java Flight Recorder.
Este artigo aborda como corrigir problemas de OOM do contêiner. Para corrigir problemas de OOM da JVM, verifique ferramentas como despejo de heap, despejo de thread e Java Flight Recorder. Para obter mais informações, consulte Capturar o despejo de heap e o despejo de thread manualmente e usar o Java Flight Recorder no Azure Spring Apps.
Corrigir problemas de reinicialização do aplicativo devido ao OOM
As seções a seguir descrevem as ferramentas, as métricas e as opções da JVM que podem ser usadas para diagnosticar e corrigir problemas de OOM do contêiner.
Exibir alertas na página Resource Health
A página Resource Health no portal do Azure exibe eventos de reinicialização do aplicativo devido ao OOM do contêiner, conforme mostrado na seguinte captura de tela:
Configurar o tamanho da memória
As métricas Uso da memória do aplicativo, jvm.memory.used
e jvm.memory.committed
exibem o uso da memória. Para obter mais informações, consulte a seção Métricas nas Ferramentas para solucionar problemas de memória. Configure os tamanhos máximos de memória nas opções da JVM para garantir que a memória esteja abaixo do limite.
A soma dos tamanhos máximos de memória de todas as partes no modelo de memória Java deve ser inferior à memória real do aplicativo disponível. Para definir os tamanhos máximos de memória, consulte o layout de memória típico descrito na seção Layout de uso de memória no Gerenciamento de memória Java.
Encontre um equilíbrio ao definir o tamanho máximo da memória. Quando o tamanho máximo definido da memória é muito alto, há um risco de OOM do contêiner. Quando o tamanho máximo definido da memória é muito baixo, há um risco de OOM da JVM, e a coleta de lixo será e retardará o aplicativo.
Controlar memória heap
Você pode definir o tamanho máximo do heap usando as opções da JVM -Xms
, -Xmx
, -XX:InitialRAMPercentage
e -XX:MaxRAMPercentage
.
Talvez seja necessário ajustar as configurações máximas de tamanho do heap quando o valor de jvm.memory.used
for muito alto nas métricas. Para obter mais informações, consulte a seção jvm.memory.used/committed/max das Ferramentas para solucionar problemas de memória.
Controlar memória direta
É importante definir a opção JVM -XX:MaxDirectMemorySize
pelos seguintes motivos:
- Talvez você não observe quando estruturas como nio e gzip usam a memória direta.
- A coleta de lixo da memória direta só é tratada durante a coleta de lixo completa, e a coleta de lixo completa ocorre somente quando o heap está quase cheio.
Normalmente, você pode definir MaxDirectMemorySize
como um valor menor que o tamanho da memória do aplicativo menos a memória heap menos a memória não heap.
Controlar o metaspace
Você pode definir o tamanho máximo do metaspace definindo a opção JVM -XX:MaxMetaspaceSize
. A opção -XX:MetaspaceSize
define o valor limite para disparar a coleta de lixo completa.
A memória do metaspace geralmente é estável.