Aplicação Java com Jboss travando a todo instante

Pessoal,
Tenho uma aplicação em Java com Jboss rodando em um servidor linux (da amazon), porém fica travando toda hora. EU restarto o jboss mas depois de uns 5 minutos já trava de novo e eu não consigo acessar a aplicação. Eu verifiquei que ele atinge quase que o máximo da memória do servidor. Tem alguma configuração que consigo fazer sem precisar aumentar a memória do servidor?

Você pode:

  1. tentar melhorar o código, procurar pontos de gargalo e tentar implementa-los de formas diferentes, que utilizem menos memória. Tenta olhar também os pools de conexão/EJB/threads, isso pode ser ajustado;

  2. otimizar o garbage collector para a tua aplicação específica. O primeiro passo é entender como funciona o GC. Depois, entender o que pode ser customizado através de parâmetros. Em seguida, estudar tua aplicação e tentar entender como é o “memory footprint” dela. São objetos grandes que vivem pouco tempo? Objetos pequenos que vivem muito tempo? Com isso você pode ajustar o GC para atuar da melhor forma possível. Tunar o GC é uma arte;

  3. ignorar todos os anteriores, aumentar as configs da máquina e pagar mais.

Conforme o @lvbarbosa colocou, o primeiro passo é rever o teu código e certificar-se de que ele está o mais otimizado possível.
Como?
Procure por loops (for, while, do/while).
Verifique Strings (lembre-se, casa String é um novo objeto e cada objeto ocupa, mesmo que mínimo, espaço em memória).
Verifique se a tua codificação está adequada, tente substituir elementos de programação estruturada (como os laços de repetição e ifs) por orientação a objetos.
Pools de conexão também podem causar problemas. Verifique se o JBoss está configurado para encerrar as “idle connections”. Está usando jdbc? Então certifique-se de que chamou o método close ou o flush após utilizar o objeto de Connection.
Utiliza session beans? Certifique-se de que utilza stateless ou, se utiliza stateful, garanta que ele seja liberado quando não for mais necessário.
Está usando logs ou imprimindo “no console”? Isso pode ocasionar situações chatas. Certificar-se de escrever em arquivo é a melhor solução.
Utiliza JPA? Tem certeza que as suas entidades são lazy? Fetch eager nem sempre é necessário.
Estes são pontos que podem causar consumo exagerado de memória. Há outros, mas resolvendo estes, mais da metade do caminho foi alcançado.

Você pode usar php.

ps: na verdade, vc pode até continuar usando Java, mas evite usar servidores de aplicações em infraestrutura de nuvem sob demanda.

1 curtida

Porque?

Em PHP não existe sistema que apresenta lentidão?
Óbvio que o consumo de memória de um apache httpd é muito menor que o de uma JVM que sustenta um JBoss e a aplicação java dentro dele. Porém, se ele não souber como otimizar o código ou mesmo gerenciar coisas fundamentais no ambiente, vai continuar com os mesmos problemas. Talvez demorem mais a aparecer, mas eles estarão lá.

Não sei quais são as necessidades dele, mas se for só para trafegar dados via Http, usar servidor de aplicação realmente é um custo desnecessário. Hibernate/JPA é outro consumidor de memória, que dependendo de como é usado pode virar uma bomba, se o programador provocar n+1 querys gerados por lazys, além de cache que muitas vezes é desnecessário, nem sempre aplicação precisa hibernar dados, então o motivo muitas vezes de usar hibernate é porque o programador quer fugir de SQL.

Sim! E como quase tudo nessa vida, a maioria dos programadores simplesmente se limita a dar uma olhada num blog ou numa página de um livro qualquer e esquece de ir mais a fundo. Eu sempre digo que pode usar hibernate/jpa para tudo, mas que é melhor ir pelo caminho mais simples. Tem N coisas que o hibernate e o jpa não facilitam. Outras n que eles complicam.
Mas, não podemos negar que SQL é uma pedra no sapato de vários desenvolvedores. A ideia geral é que não se precisa aprender a construir queries…

Porque não?
AWS já tem o Elastic Beanstalk pra facilitar o deploy de aplicações, conectar com banco de dados, escalonamento, backup, telemetria, etc. portanto usar JBoss não faz sentido.

Mas o principal é que um computador na infraestrutura de nuvem deve ser capaz de falhar e ser substituído rapidamente, ex: se uma instancia tem problema ou fica instável, ela é eliminada e outra criada. Se você roda JBoss com vários serviços, todos eles ficarão indisponíveis até seu monolítico ser reiniciado (além de demorar mais pra reiniciar um monolítico do que um microserviço).

Se o mesmo acontece numa arquitetura de microserviços, apenas uma parte do sistema fica indisponível e por um tempo menor.

Concordo, mas ter que reiniciar a cada 5 minutos não é problema de lentidão.
Parece mais problema de falta de estudo sobre quanto de memória o sistema precisa pra funcionar. O certo seria fazer esse estudo e depois, de posse dessa informação, decidir o que fazer (contratar uma instancia maior x otimizar sua app x usar uma stack que consome menos memória).

O bom da infraestrutura sob demanda é que é sob demanda, isso inclui a memória contratada. Você não esta preso a uma configuração específica de hardware, então não há necessidade de perder tempo otimizando código como se fosse uma infra sob premissa. :slight_smile:

@dsystem, apesar das dicas apresentadas serem corretas, varrer o código procurando por coisas que podem estar causando o travamento, nao é uma maneira muito prática de encontrar o problema.

Esse problema acontece apenas em produçao ou se você roda localmente o sistema também acontece?

Você pode tentar rodar um profiler na sua aplicaçao, que irá lhe mostrar o que exatamente está consumindo memória.

Porque a experiencia do programador OO usando SQL tem sido concatenar strings pra criar queries, e mapear resultsets para objetos. Tb conhecido por incompatibilidade objeto-relacional.

Mas DBAs amam SQL.