Exception in thread "http-bio-8080-exec-3" java.lang.OutOfMemoryError: Java heap space

Boa tarde Pessoal,

estou fazendo uma consulta numa tabela com 800 mil registros e umas 50 colunas ao executar

  sql = "SELECT * FROM "+pTabela;
  connMySql = obtemConexaoMySql(pBase);
  java.sql.Statement st = connMySql.createStatement();   
  ResultSet rs = st.executeQuery(sql);

Ao executar apresenta o seguinte erro

Exception in thread "http-bio-8080-exec-3" java.lang.OutOfMemoryError: Java heap space at com.mysql.jdbc.MysqlIO.nextRowFast(MysqlIO.java:2145) at com.mysql.jdbc.MysqlIO.nextRow(MysqlIO.java:1922) at com.mysql.jdbc.MysqlIO.readSingleRowSet(MysqlIO.java:3423) at com.mysql.jdbc.MysqlIO.getResultSet(MysqlIO.java:483) at com.mysql.jdbc.MysqlIO.readResultsForQueryOrUpdate(MysqlIO.java:3118) at com.mysql.jdbc.MysqlIO.readAllResults(MysqlIO.java:2288) at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2709) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2728) at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2678) at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1612) at database.conexao.MovRegistros(conexao.java:93) at comissionamento.executaprocessoComissionamento.doGet(executaprocessoComissionamento.java:100) at javax.servlet.http.HttpServlet.service(HttpServlet.java:621) at javax.servlet.http.HttpServlet.service(HttpServlet.java:722) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585) at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source)

Já aumentei a memoria no arquivo ini do eclipse.
Alguem poderia me ajudar ??

sql = "SELECT * FROM "+pTabela; 

Não está faltando um “WHERE” aqui? O que tu vai fazer com um ResultSet de 800 mil linhas? Deixe o banco trabalhar um pouco, pô :slight_smile:

Concordo com o entanglement… pelo menos página essa consulta aí!

Então, neste caso a aplicação esta fazendo uma consulta no mysql e depois jogando para o oracle
por isso está massa tão grande.
Mais como faria para paginar isso no mysql ??

Olha, você poderia fazer isso de algumas formas…
mas talvez o ideal seja formular uma lógica que use o recurso COUNT e também os recuros LIMIT e OFFSET do MySQL.

Aí é com você, monte alguma lógica para ir pegando os valores determinando um número de valores por vez atravéz do LIMIT e utilizando o OFFSET como um ponteiro “incrementando-o” a cada busca. E o CONT você usa para controle da quantidade de registros mesmo e o fim da iteração.

Aqui tem um exemplo pequeno e simples de LIMIT e OFFSET: http://www.vivaolinux.com.br/dica/SELECT-para-paginacao-no-MySQL.

Espero ter ajudado, mas se não fui muito claro é só falar! :smiley:

Só tem uma coisa que não entendi, como vou fazer o resultset pegar a cada vez uma nova massa a partir de onde parou a outra.

Só tem uma coisa que não entendi, como vou fazer o resultset pegar a cada vez uma nova massa a partir de onde parou a outra.

outra coisa, e que acho que o problema e pela quantidade de colunas.
Será que isso resolverá ?

aszarael,

Supondo que para a memória não “estorar” é necessário trazer apenas 15 registros do banco, porém a tabela (por exemplo: produtos) possui 50 registros…

int limite = 15;
int cursor = 0;
int qtdeRegistros = 50; //Quantidade obtida através de um COUNT()

while (cursor < qtdeRegistros){
    //busca as informações no BD através do SELECT:
    String sql = "SELECT * FROM Produtos LIMIT " + limite + " OFFSET " + cursor;

    //faz o que precisa ser feito

    cursor += limite;
}
  • ou - assim… desta forma você vai pegando os valores sempre do ponto onde parou, assim como explica também no link acima que te passei.

Mas… só por curiosidade… quantas colunas existem nesta tabela para que você possa deduzir isso? :?:

A TABELA TEM 50 COLUNAS E 800 MIL REGISTROS.
MAIS ENTENDI COMO FUNCIONA O LIMIT E O OFFSET AGORA.
VALEU VOU TESTAR AQUI E VER SE RESOLVE.

Beleza, testa aí e depois fala o resultado.

Mas o problema era sim a quantidade de registros que eram jogados de uma vez…
…mas pra ser sincero não tenho certeza se o número de colunas influenciaria, talvez sim, mas também talvez se resolveria diminuindo mais a quantidade de registros a buscar no banco.

A TABELA TEM 50 COLUNAS E 800 MIL REGISTROS.
MAIS ENTENDI COMO FUNCIONA O LIMIT E O OFFSET AGORA.
VALEU VOU TESTAR AQUI E VER SE RESOLVE.

A TABELA TEM 50 COLUNAS E 800 MIL REGISTROS.
MAIS ENTENDI COMO FUNCIONA O LIMIT E O OFFSET AGORA.
VALEU VOU TESTAR AQUI E VER SE RESOLVE.

A TABELA TEM 50 COLUNAS E 800 MIL REGISTROS.
MAIS ENTENDI COMO FUNCIONA O LIMIT E O OFFSET AGORA.
VALEU VOU TESTAR AQUI E VER SE RESOLVE.

A TABELA TEM 50 COLUNAS E 800 MIL REGISTROS.
MAIS ENTENDI COMO FUNCIONA O LIMIT E O OFFSET AGORA.
VALEU VOU TESTAR AQUI E VER SE RESOLVE.

Deu certo aqui pessoal.
Muito Obrigado