Problemas com coletor de lixo do java

11 respostas
zoren

E ai povo,

Atualmente eu andei tendo problemas com o coletor de lixo do java em uma aplicação web no cliente, isso começou do nada.

Depois de algum tempo rodando, a aplicação simplesmente para de funcionar, notei que nos logs da aplicação aparecem erros imensos e o último é sempre do tipo

Caused By: java.net.SocketException: Too many open files
    ....

Isso fica direto toda vez que a aplicação tenta acessar o banco ou alguém tenta acessar uma página dela.

Começou a acontecer de um tempo para cá, antes a aplicação rodava meses sem parar, agora roda algumas horas e morre.

Fazendo testes e pesquisando na internet, descobri que o linux (o SO do meu cliente é linux, e esse não é o problema, pois tenho outro cliente rodando a mesma aplicação em linux e o problema não ocorre) tem um limite para arquivos abertos.

Com isso fiquei monitorando a quantidade de arquivos abertos e descobri que a aplicação vai abrindo arquivos até estourar o limite.

Fiz o mesmo teste localmente e a quantidade de arquivos ficava entre 100 e 400, qdo atingia por volta de 300 e 400, o coletor de lixo do java passava e limpava tudo.

Porém no meu cliente isso não ocorre, os testes que eu fiz foi na mesma distribuição que ele usa, e o servidor onde a aplicação está instalada, só tem java, tomcat e mysql e ainda por cima só roda a minha aplicação.

Mas ocorre algo mais estranho ainda, quando alguém envia uma requisição para a aplicação, o coletor de lixo do java simplesmente passa e libera os objetos da memória, a quantidade de arquivos cai para mais ou menos uns 300.

Segundo o meu cliente não houve nenhuma alteração naquele servidor.

Alguém sabe o que pode ser?

As versões dos programas instalados

Tomcat 6.0.18
Java 1.6.0_13u
MySQL 5.1

A aplicação usa Hibernate/JPA e Spring

11 Respostas

Vmaia

Olá,

Ve se te ajuda…

zoren

Eu já tinha visto esse

Pra mim não funciona, o número de arquivos abertos aumenta e não abaixa, só quando faço alguma requisição http para a aplicação

aumentar esse limite só vai fazer com que a aplicação demore um pouco mais para travar.

ViniGodoy

Você chama o comando close() explicitamente, dentro de um bloco finally?
Qual a velocidade com que você abre e fecha conexões sockets?

Vmaia

Entendi, …

  • está ocorrendo mais acessos ao teu sistema, fazendo com que ele sobrecarregue ?
  • por acaso a aplicação está deixando de fechar as conecções ?
  • tem certeza que não houve mudança no ambiente ? [pois, se esta tudo funcionando e agora não … provavelmente alguem alterou algo. ]
    — problema de memória ?
  • vc consegue reproduzir essa situação em algum outro lugar ?
    — tente trocar o binário do aplicativo… caso não tenha como reproduzir o erro, pode ter [suposição] corrompido o pacote. =D
zoren

ViniGodoy, eu fecho tudo que eu abro na aplicação, só não posso garantir quanto ao Axis2 e ao driver do MySQL

Vmaia, pelo contrário, quando tem acesso o coletor de lixo do java funciona e o problema não acontece. Eu havia refeito o deploy da aplicação, eu tinha corrigido um bug, consertado um erro num JSP e criado clientes para acessar outros webservices mas as alterações não fizeram diferença para esse cliente, já tentei colocar a versão antiga para rodar e dá o mesmo erro.

Já fiz o mesmo procedimento numa maquina virtual com o mesmo linux e as mesmas versões dos programas que estão instalados e nada do erro.

Problema de vazamento de memória o tomcat deve ter, mais o coletor de lixo do java aparentemente nem passa, pq a quantidade de arquivos abertos pelo java aumenta cada vez mais e nada de baixar.

E no outro cliente que tem linux a aplicação roda normal e tem bem mais coisa no servidor dele.

Respondendo a segunda pergunta do ViniGodoy, a aplicação tem um monte de threads que rodam em background, tem 2 que rodam de 5 em 5 minutos que fazem consulta no banco e pegam arquivos e enviam dados a webservices.

Tem outras 3 que fazer consultas em webservices para verificar o funcionamento de serviços e mais outras duas que usam a internet, tem mais duas que rodam de meia em meia hora que fazer umas consultas no banco para verificar o sistema.

Eu não mexo com socket diretamente, quem usa é o spring, mysql, javamail, axis

zoren

Eu desconfiava do tamanho da aplicação que tem atualmente 36 megas

Só me sobrou algumas alternativas

  • Tentar reinstalar o java;
  • Fazer um programa que fique fazendo requisições para a página da aplicação (aparentemente funciona);
  • Falar pro cliente que é problema do SO dele;

Eu já perguntei umas 300 vezes se ele alterou alguma coisa no servidor, mas ele sempre diz que não mudou nada.

Minha unica explicação para o problema é o servidor estar possuído por algum script do mau.

Também notei que a aplicação no servidor dele demora mais que o normal para realizar algumas tarefas as vezes penso que é devido a quantidade de registros no banco.

Também pensei que poderia ser o banco que estivesse segurando as conexões, fiquei vendo a quantidade de usuários conectados e nada, tem apenas um.

[edit]

Eu não conheço nada da arquitetura do linux, mas existe algo que pudesse acontecer com o SO que impedisse que o java conseguisse coletar a memória usada.

Aparentemente, o coletor de lixo só funciona se vc fizer uma requisição http para a aplicação antes que ela trave, não sei se enviar alguma requisição para o tomcat dá o mesmo efeito, vou testar isso para ver o que acontece.

pmlm

Linux 32 ou 64 bits?

zoren

32

pmlm

Ok. Já tive uns problemas estranhos mas foi com 64 bits.

zoren

pmlm:
Ok. Já tive uns problemas estranhos mas foi com 64 bits.

Quais foram os problemas?? Talvez me ajude

pmlm

Problemas de performance estranhos, aleatórios. A solução foi instalar a JVM para 32 bits (estranho, eu sei)

Criado 17 de maio de 2010
Ultima resposta 18 de mai. de 2010
Respostas 11
Participantes 4