Consumo excessivo de memória no Tomcat

7

Eu tenho um novo servidor rodando o Ubuntu 11.04 (Natty) (64 bits). Comecei instalando openjdk e tomcat6 . Quando o servidor Tomcat é iniciado, ele usa imediatamente 480+ MB de memória. Isso parece fora de proporção e eu estou querendo saber se alguém tem uma solução para fazer com que o Tomcat use 200-300 MB (ou menos) de memória.

Eu usei memtop para ver isso: (Observação: removi todas as entradas, exceto as grandes. A entrada de 499 MB é Tomcat)

  user@xyz:~# python memtop-0.9.py
  PID |   private/writ. mem |command
      |  current | previous |(truncated)
19776 | 499.3 MB |    +++++ |/usr/lib/jvm/java-6-openjdk/bin/java-Djava.util.logging.config.file=/var/lib/tomcat6/conf/logging.properties-Djava.awt.headless=true-Xm
18082 | 148.6 MB |    +++++ |/usr/sbin/mysqld
 1385 |   3.6 MB |    ++    |pythonmemtop-0.9.py
RAM usage:  ==============================================  69.3 %

Além disso, você pode ver quais pacotes JDK e Tomcat eu instalei:

user@xyz:~# dpkg --get-selections | grep jdk
default-jdk                                     install
openjdk-6-jdk                                   install
openjdk-6-jre                                   install
openjdk-6-jre-headless                          install
openjdk-6-jre-lib                               install

user@xyz:~# dpkg --get-selections | grep tomcat
libtomcat6-java                                 install
tomcat6                                         install
tomcat6-admin                                   install
tomcat6-common                                  install
tomcat6-user                                    install

O script de inicialização do Tomcat define Xmx para 128M :

JAVA_OPTS="-Djava.awt.headless=true -Xmx128M"

Alguém tem alguma idéia do que eu poderia fazer para reduzir o consumo de memória a algo mais razoável? Eu não entendo porque a JVM e o Tomcat juntos precisariam consumir tanta memória.

EDITOS

Por isso, eu baixei o Tomcat 6 diretamente e executei o script de inicialização. Lembre-se de que nenhum valor Xmx foi definido neste momento. Ao executar isso, o memtop mostra que o Tomcat está usando o 737 MB de memória!

Isso me leva a acreditar que há um problema com openjdk usando uma quantidade séria de memória para a JVM.

Eu tentei a mesma coisa com um novo download .zip do Tomcat 7 - o mesmo problema. Ele estava usando 740 MB de memória.

Eu instalei o Sun JRE / JDK. O consumo de memória caiu para cerca de 400 MB (abaixo dos quase 500 MB). Isso ainda é mais uso de memória do que eu preferiria!

(sun-java6-bin, sun-java6-jdk, sun-java6-jre)

Quando executo top , obtenho isto:

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
13749 tomcat6   20   0  481m  68m 9892 S    0  7.4   0:02.85 java

Eu percebo e espero que uma máquina / JVM de 64 bits use mais memória, mas não esperava que fosse tão alto. Estou correndo em uma VM que só está me garantindo 512MB.

    
por Tanner 01.08.2011 / 20:05

1 resposta

2

---- Editado para fornecer exemplo, pois o ponto não está aparecendo ----

Um processo é iniciado e pede 1 GB de memória.

Esse processo então inicia oito threads (todos com acesso à memória alocada de 1 GB).

Alguém executa uma ferramenta para determinar quanta memória está sendo usada. A ferramenta funciona da seguinte forma:

  1. Encontre todos os itens agendáveis (cada thread).
  2. Veja quanta memória ele pode acessar.
  3. Adicione essa memória em conjunto
  4. Denunciar a soma.

A ferramenta relatará que o processo está usando 9 GB de memória, quando é óbvio que existem oito threads gerados (e o thread para o processo original) todos usando o mesmo GB de memória.

É um defeito em como algumas ferramentas relatam memória; no entanto, não é um defeito facilmente consertável (como consertar isso, seria necessário alterar a saída de algumas ferramentas muito antigas (mas importantes)). Eu não quero ser o cara que reescreve top ou ps, isso tornaria o SO não POSIX.

---- O post original segue ---- Algumas versões de ferramentas de relatório de memória (como o top) confundem, erroneamente, os threads (que têm acesso à mesma memória) aos processos. Como resultado, uma instância do tomcat que gera cinco threads não informa o consumo de memória em cinco vezes.

A única maneira de garantir é listar os processos com seu consumo de memória individualmente e, em seguida, ler a memória de um dos encadeamentos (que está sendo listado como um processo). Dessa forma, você sabe o verdadeiro consumo de memória do aplicativo. Se você confiar em ferramentas que fazem a adição para você, você irá superestimar a quantidade de memória realmente usada pelo número de threads referenciando a mesma memória compartilhada.

Eu tive caixas com 2 GB de memória (e 1 GB de swap) informando que ~ 7 GB de memória estava em uso em um aplicativo particularmente pesado antes.

Para entender melhor como a memória é relatada por muitas ferramentas, procure aqui . Se o código python estiver analisando o texto de uma dessas ferramentas ou obtendo os dados das mesmas chamadas de sistema, estará sujeito aos mesmos erros na memória de relatórios.

    
por 01.08.2011 / 21:45