Estou com um problema em ambiente de produção Websphere, onde uma aplicação que utiliza os frameworks Ibatis e Struts 1.1 está derrubando o WAS por out of memory.
Eu usei o heap analyzer da IBM para investigar os dumps e aparentemente o erro acontece no retorno de uma query no banco de dados Oracle.
A aplicação web chama uma stored procedure no Oracle através do Ibatis. Esta procedure popula uma tabela temporária (global temporary table) e posteriormente é feito um SELECT nesta tabela (tudo isto está dentro de uma transação).
Alguém já teve um problema semelhante?
Obrigado.
uma vez me chamaram para fazer uma consultoria num problema destes…
o sql estava levantando ± uns 350 mb, e depois ainda ficava na sessao do usuario… se 2 ou 3 usuarios fizessem esta busca, ja era…
mas no seu caso só olhando para saber… outofmemory ou é um loop infinito que daria no ambiente local tb… ou é porque vc pode nao estar liberando recursos,… fechando statements, resultsets, etc… ou sua query pode ser gigantesca.
Você precisa ajustar a consulta para, entre outras coisas, utilizar o RowHandler:
Recomendo voce utilizar um profiler como JProfiler para ter um analise completo da tua aplicação.
http://www.mouseoverstudio.com/blog/?p=67
Aldrin Leal
Pelo o que eu entendi, o RowHandler é um mecanismo de manipular o resultado da query linha por linha antes de o Ibatis popular a Collection.
Você tem alguma dica de como utilizar o RowHandler para resolver este problema?
O termo correto não é antes, e sim ao invés.
O fato é o seguinte: Muitos drivers JDBC (MySQL, particularmente), não usam a metáfora de cursor no servidor, que seria o ideal. Isso pode acontecer por vários motivos (em particular, pelo próprio servidor não oferecer - calma, o MySQL oferece, mas drivers de alguns bancos acabam não fazendo), mas o motivo principal é aquela velha tendência do anaprodégua não chamar o close no resultset.
Ok, dito isso, vamos comentar sobre o seu pobrema. Bem, o que você pretende fazer com os dados, afinal de contas? Se tem tabela temporária, é provavelmente algum processamento oneroso.
Se você tá fazendo isso em uma aplicação web (a julgar pelo WebSphere), minha primeira sugestão é: desvincule isso do request, usando algo como o Quartz, Message Driven Beans, ou o próprio recurso de Asynchronous Beans do WebSphere, como também o de Object Pools.
Em um projeto em particular, lembro-me que o mesmo exigia salvar quantidades absurdas de dados em consultas. A abordagem foi semelhante, mas um pouco mais ortodoxa: O nosso RowHandler lia de uma consulta e… Salvava em outra. Mas a outra conexão era uma base de dados H2.
Pensando bem, uma saída intermediária seria você utilizar o CachedRowSet. Em particular, eu apenas me preocuparia em serializá-lo utilizando Fast-Infoset. Mas, eis, são apenas opiniões minhas. 
Aldrin Leal
Os dados são utilizados em uma consulta. A Collection retornada pelo Ibatis é colocada na request e exibida para o usuário em um JSP.
O comportamento da aplicação está meio esquisito, pois está dando Out of memory mesmo quando o usuário não está solicitando um conjunto grande de dados. Eu estou utilizando o recurso de groupBy do Ibatis, para facilitar uma consulta de referência cruzada. Eu pesquisei no mail-archive do Ibatis, e acho que isso pode estar melando a aplicação:
http://www.mail-archive.com/user-java@ibatis.apache.org/msg10625.html
Cara, tem certeza de quê a query está realemente okay? Não tá rolando cartesiano não? Executa a query com count pra ter certeza de que está tudo okay. Usei iBatis com querys grandes (gigantes) e apenas uma vez tive problemas com out of memory …
Por favor, copie a query e o xml aqui (a versão do ibatis tb ajuda). Com isso poderemos “ver” o quê está rolando …
Woody
Tenho certeza absoluta que a query está correta. A query é super simples, utilizando apenas a tabela temporária (global temporary table) gerada pela stored procedure.
Cara, posta aí o xml e o trecho de dao que está retornando essas linhas …
Você pode dar alguma idéia da ordem de magnitude? Em particular, coisas como quantos registros essa consulta devolve, e em quanto tempo (caso demore um pouco)
Olhando pela documentação do ibatis, vi que o groupBy pode gerar MUITOS resultados em memória. Então assim, uma tabela na ordem de centenas de milhares de registros pode acabar gerando vários detalhes que ocupam MUITA memória. Talvez o ideal seja você só ter esta chave e então, adotar uma estrutura de cache ou algo como o LazyMap, do commons-collections.
Aldrin Leal, sei não. O iBatis resolveu a query. Depois de resolver a query o iBatis transfere os dados dentro do resultset para um TO qq (ou map) …
Pelo que o André falou o erro está nessa fase (se fosse na fase do sql teriámos um SQLException)
Insisto: posta o mapping e o sql aí …
agostinhost,
Desculpa, mas não entendi nada do que você falou. Na dúvida, vou usar o princípio de taxa sinal ruído e fingir que não ouvi nada 
pq se dar ao trabalho de comentar então?
Diante das opções, me pareceu a menos rude. Obrigado pela atenção.