A JVM gerencia dois tipos de memória, heap e não heap. O heap é para uso dos desenvolvedores, como mencionado acima, ele é criado quando a JVM é iniciada; o não-heap é reservado para a própria JVM armazenar informações de classe; É diferente do heap não liberará espaço durante o tempo de execução.
1. Tipo de estouro de memória
1. java.lang.OutOfMemoryError: espaço PermGen
A JVM gerencia dois tipos de memória, heap e não heap. O heap é para uso dos desenvolvedores, como mencionado acima, ele é criado quando a JVM é iniciada; o não-heap é reservado para a própria JVM armazenar informações de classe; É diferente do heap não liberará espaço durante o tempo de execução. Se o aplicativo da web usar um grande número de jars de terceiros ou se o aplicativo tiver muitos arquivos de classe e a configuração MaxPermSize for pequena, exceder o limite também fará com que a memória ocupe demais e cause estouro, ou o Tomcat irá não limpar a frente durante a implantação a quente O ambiente carregado apenas mudará o contexto para o recém-implantado e haverá cada vez mais conteúdo não empilhável.
O nome completo do espaço PermGen é espaço de geração permanente, que se refere à área de armazenamento permanente da memória. Essa memória é usada principalmente pela JVM para armazenar informações de classe e meta que serão colocadas no espaço PermGen. é carregado pelo Loader e armazena instâncias de classe (Instância). A área de heap é diferente, o GC (Coleta de Lixo) não limpará o espaço do PermGen durante a execução do programa principal, portanto, se seu aplicativo tiver muito CLASS, o PermGen é provável que apareça. erro de espaço, esse erro é comum quando o servidor web pré-compila JSP. Se o seu WEB APP utiliza um grande número de jars de terceiros e seu tamanho excede o tamanho padrão do jvm (4M), esta mensagem de erro será gerada.
Um melhor exemplo de configuração: (após verificação por mim mesmo, desde que usei esta configuração, o Tomcat nunca mais morreu)
definir JAVA_OPTS=-Xms800m -Xmx800m -XX:PermSize=128M -XX:MaxNewSize=256m -XX:MaxPermSize=256m
No Linux, adicione uma linha de código conforme mostrado em vermelho em tomcathome/conf/catalina.sh: você pode aumentar a memória do tomcat jvm, para que seja menos provável que ocorra estouro de memória!
# ----- Execute o comando solicitado ---------------------------------------- -
JAVA_OPTS="-server -Xms512m -Xmx2048m -XX:PermSize=128m -XX:MaxNewSize=256m -XX:MaxPermSize=256m"
# Bugzilla 37848: só gera isso se tivermos um TTY
2. java.lang.OutOfMemoryError: espaço Javaheap
A primeira situação é um complemento, e o principal problema ocorre nesta situação. Seu espaço padrão (ou seja, -Xms) é 1/64 da memória física e o espaço máximo (-Xmx) é 1/4 da memória física. Se restar menos de 40% da memória, a JVM aumentará o heap para o valor definido por Xmx. Se a memória restante exceder 70%, a JVM diminuirá o heap para o valor definido por Xms. Portanto, as configurações Xmx e Xms do servidor geralmente devem ser definidas da mesma forma para evitar o ajuste do tamanho do heap da máquina virtual após cada GC. Supondo que a memória física seja infinita, a memória JVM máxima depende do sistema operacional. Geralmente, a máquina de 32 bits está entre 1,5g e 3g, enquanto a máquina de 64 bits não tem limite.
Nota: Se Xms exceder o valor Xmx ou a soma do valor máximo de heap e do valor máximo não heap exceder o limite máximo da memória física ou do sistema operacional, o servidor não será iniciado.
O papel do GC de coleta de lixo
A frequência de JVM chamando GC ainda é muito alta e a coleta de lixo é realizada em duas situações principais:
Quando o thread do aplicativo está ocioso; o outro é quando o heap de memória Java é insuficiente, o GC será chamado continuamente. Se a reciclagem contínua não puder resolver o problema de heap de memória insuficiente, um erro de falta de memória será relatado. Como esta exceção depende do ambiente operacional do sistema, é impossível prever quando ocorrerá.
De acordo com o mecanismo do GC, a execução do programa causará alterações no ambiente operacional do sistema, aumentando a chance de acionamento do GC.
Para evitar esses problemas, o projeto e a escrita de programas devem evitar a ocupação de memória por objetos de lixo e a sobrecarga do GC. Chamar System.GC() explicitamente só pode sugerir que a JVM precisa reciclar objetos de lixo na memória, mas não precisa ser reciclada imediatamente.
Uma é que isso não pode resolver o problema de falta de recursos de memória e também aumentará o consumo de GC.
2. Composição da área de memória JVM <BR>Basta falar sobre heap e stack em java
Java divide a memória em dois tipos: um é memória de pilha e o outro é memória heap.
1. Variáveis de tipo básico e variáveis de referência de objeto definidas na função são alocadas na memória de pilha da função;
2. A memória heap é usada para armazenar objetos e arrays criados por new. Quando uma variável é definida em uma função (bloco de código), Java aloca espaço de memória para a variável na pilha. libere-o automaticamente. Remova o espaço de memória alocado para a variável; a memória alocada no heap é gerenciada pelo coletor de lixo automático da máquina virtual Java. A vantagem do heap é que o tamanho da memória pode ser alocado dinamicamente e o tempo de vida. não precisa ser informado ao compilador com antecedência, pois está na memória e é alocado dinamicamente em tempo de execução. A desvantagem é que a memória deve ser alocada dinamicamente em tempo de execução e a velocidade de acesso é lenta;
A vantagem da pilha é que a velocidade de acesso é mais rápida que a do heap. A desvantagem é que o tamanho e a vida útil dos dados armazenados na pilha devem ser determinísticos e inflexíveis.
O heap java é dividido em três áreas: Novo, Antigo e Permanente
GC tem dois threads:
Os objetos recém-criados são alocados para a área Nova. Quando a área for preenchida, ela será movida para a área Antiga pela thread auxiliar do GC. Quando a área Antiga também for preenchida, a thread principal do GC será acionada para percorrer todos os objetos nela. a memória heap. O tamanho da área Antiga é igual a Xmx menos -Xmn
Ajuste de pilha de armazenamento de pilha Java: os parâmetros são +UseDefaultStackSize -Xss256K, o que significa que cada thread pode solicitar espaço de pilha de 256k. Cada thread tem sua própria pilha.
3. Como configurar memória virtual na JVM Dica: Na JVM, se 98% do tempo for usado para GC e o tamanho do Heap disponível for menor que 2%, esta mensagem de exceção será lançada.
Dica: O tamanho máximo de heap não deve exceder 80% da memória física disponível. Geralmente, as opções -Xms e -Xmx devem ser definidas com o mesmo valor e -Xmn deve ser 1/4 do valor -Xmx.
Dica: A memória inicial alocada pela JVM é especificada por -Xms, e o padrão é 1/64 da memória física, a memória máxima alocada pela JVM é especificada por -Xmx, e o padrão é 1/4 da memória física; memória.
Por padrão, quando a memória heap livre for inferior a 40%, a JVM aumentará o heap até o limite máximo de -Xmx; quando a memória heap livre for superior a 70%, a JVM reduzirá o heap até o limite mínimo de; -Xms. Portanto, o servidor geralmente define -Xms e -Xmx como iguais para evitar o ajuste do tamanho do heap após cada GC.
Dica: Supondo que a memória física seja infinita, o valor máximo da memória JVM tem um ótimo relacionamento com o sistema operacional.
Simplificando, embora um processador de 32 bits tenha um espaço de memória controlável de 4 GB, o sistema operacional específico imporá um limite.
Esse limite é geralmente de 2 GB a 3 GB (em geral, é de 1,5 G a 2 G em sistemas Windows e de 2 G a 3 G em sistemas Linux), e não haverá limite para processadores acima de 64 bits.
Nota: Se Xms exceder o valor Xmx ou a soma do valor máximo de heap e o valor máximo não heap exceder o limite máximo da memória física ou do sistema operacional, o servidor não será iniciado.
Dica: Defina NewSize e MaxNewSize como iguais, e o tamanho do "novo" não deve ser maior que a metade do "antigo". O motivo é que se a área antiga não for grande o suficiente, o GC "principal" será acionado com frequência. , o que reduz bastante o desempenho.
JVM usa -XX:PermSize para definir o valor inicial da memória não heap. O padrão é 1/64 da memória física;
O tamanho máximo da memória não heap é definido por XX:MaxPermSize. O padrão é 1/4 da memória física.
Solução: definir manualmente o tamanho do heap
Modifique TOMCAT_HOME/bin/catalina.bat
Adicione as seguintes linhas acima de "echo "Using CATALINA_BASE: $CATALINA_BASE"":
JAVA_OPTS="-servidor -Xms800m -Xmx800m -XX:MaxNewSize=256m"
4. Use ferramentas de verificação de desempenho para localizar vazamentos de memória:
A ferramenta JProfiler é usada principalmente para verificar e rastrear o desempenho de sistemas (limitado ao desenvolvimento Java). JProfiler pode monitorar a operação e o desempenho da JVM monitorando constantemente o uso de memória do sistema, coleta de lixo, status de execução do thread e outros meios a qualquer momento.
1. A memória do servidor de aplicativos fica excessivamente ocupada por um longo período. A memória geralmente fica ocupada em um nível alto e é difícil de recuperar para um nível baixo.