Gerando arquivo texto gigantesco  XML
Índice dos Fóruns » Java Básico
Autor Mensagem
Rafael Nunes
Moderador
[Avatar]

Membro desde: 09/10/2003 13:41:06
Mensagens: 2890
Localização: sao bernardo do campo
Offline

Alguém aí já teve que gerar arquivos muito grandes?(500/600Mb)
Até agora só havia gerado coisas pequenas, e agora com a quantidade de dados, tô tomando uma surra.
Eu retorno do banco algumas milhares de linhas, e vou duplicando essas linhas dentro de um arquivo texto. Mas dependendo da quantidade de registros que retorno, ele estoura a memória do servidor(1Gb). Tem alguma forma de eu não deixar este arquivo carregado na memória? Ir adicionando somente ao final dele cada linha que retorno do banco.

Grato

------------------------------------------------------------------
"Think different? I'd be happy if most people would just think..."

http://www.yaw.com.br
http://twitter.com/rafanunes
http://twitter.com/youandwe
[Email]
louds
Moderador
[Avatar]

Membro desde: 29/04/2003 23:09:15
Mensagens: 4061
Localização: São Paulo
Offline

Se você usar um BufferedWriter/FileWriter não tem galho algum. Você não tá escrevendo em um String(Writer|Buffer) e depois pro disco né?

http://www.kumpera.net/blog/
http://www.mono-project.com/
"Each individual should work for himself. People will not sacrifice themselves for the company. They come to work at the company to enjoy themselves."
Soichiro Honda
[ICQ]
jaboot
Virtual Machine Man

Membro desde: 01/07/2005 14:25:37
Mensagens: 749
Localização: São Paulo
Offline

<chute>
Porque você não tenta dimensionar o tamanho médio do arquivo OU quantos registros você vai colocar no arquivo(em média).
Em posse dessas informações, faz um loop, grava um punhado no arquivo, fecha ele, elege o método pro gc.
E vai fazendo isso até o final de registros. Acho que vai ficar um pouco trabalhoso, mas já tive que fazer isso com VB há muito tempo atrás e funcionou.
</chute>
[MSN] [ICQ]
Rafael Nunes
Moderador
[Avatar]

Membro desde: 09/10/2003 13:41:06
Mensagens: 2890
Localização: sao bernardo do campo
Offline

louds wrote:Se você usar um BufferedWriter/FileWriter não tem galho algum. Você não tá escrevendo em um String(Writer|Buffer) e depois pro disco né?


To nada, tô fazendo um 'BufferedWriter.write(registro)' direto, mas mesmo assim tá estourando a memória do servidor. Creio que deve ser por causa da quantidade de registros (22000 * N * 4 - sendo que n pode variar de 2 a 100)

balarini wrote:
Porque você não tenta dimensionar o tamanho médio do arquivo OU quantos registros você vai colocar no arquivo(em média).

O problema é que esse arquivo é pra receita federal, tem que ser um arquivo só. Creio que na hora de ler todos os arquivos para montar um só, eu cairia no mesmo problema.

------------------------------------------------------------------
"Think different? I'd be happy if most people would just think..."

http://www.yaw.com.br
http://twitter.com/rafanunes
http://twitter.com/youandwe
[Email]
ciczan
JavaGuru
[Avatar]

Membro desde: 22/12/2004 12:57:21
Mensagens: 227
Localização: Curitiba -PR
Offline

Que eu saiba se vc usar o BufferedWriter/FileWriter ele não vai ficar guardando tudo na memória.

É possível que o que está estourando a memória é a consulta retornada e não o arquivo. Daí vc vai ter que fazer paginação ou coisa do gênero.
[MSN]
jaboot
Virtual Machine Man

Membro desde: 01/07/2005 14:25:37
Mensagens: 749
Localização: São Paulo
Offline

Rafael Nunes wrote:O problema é que esse arquivo é pra receita federal, tem que ser um arquivo só. Creio que na hora de ler todos os arquivos para montar um só, eu cairia no mesmo problema.
Acho que a gente teve um pequeno problema de comunicação
O que eu estava tentando lhe dizer é: colocar, por exemplo, 5 mil em 5 mil registros por vez, no mesmo arquivo, porque daí acho que o gc iria trabalhar, já que houve uma pequena pausa.
Ou então, sei lá, tenta criar uma thread que faça isso.
[MSN] [ICQ]
Rafael Nunes
Moderador
[Avatar]

Membro desde: 09/10/2003 13:41:06
Mensagens: 2890
Localização: sao bernardo do campo
Offline

ciczan wrote:Que eu saiba se vc usar o BufferedWriter/FileWriter ele não vai ficar guardando tudo na memória.

É possível que o que está estourando a memória é a consulta retornada e não o arquivo. Daí vc vai ter que fazer paginação ou coisa do gênero.


Tô usando um framework da empresa aqui pra manipular o resultset, depois que o louds falou fui dar uma olhada, e ele retorna uma String para cada coluna. Deve ser o excesso de objetos criados.

------------------------------------------------------------------
"Think different? I'd be happy if most people would just think..."

http://www.yaw.com.br
http://twitter.com/rafanunes
http://twitter.com/youandwe
[Email]
ciczan
JavaGuru
[Avatar]

Membro desde: 22/12/2004 12:57:21
Mensagens: 227
Localização: Curitiba -PR
Offline

Uma idéia é vc fazer várias consultas. Tipo se é pro ano inteiro, vc faz uma pra cada mês, tomando o cuidado para deixar o resultset "garbage colectable".

Ainda acho que o problema não é com o arquivo.
[MSN]
louds
Moderador
[Avatar]

Membro desde: 29/04/2003 23:09:15
Mensagens: 4061
Localização: São Paulo
Offline

O problema não é o excesso de objetos criados, mas sim quantos você mantem ao mesmo tempo em memória.

Esse teu result-set vem com 500mil registros de uma vez só? O driver faz paginaçã ou coloca tudo em memória de uma única vez?

http://www.kumpera.net/blog/
http://www.mono-project.com/
"Each individual should work for himself. People will not sacrifice themselves for the company. They come to work at the company to enjoy themselves."
Soichiro Honda
[ICQ]
Rafael Nunes
Moderador
[Avatar]

Membro desde: 09/10/2003 13:41:06
Mensagens: 2890
Localização: sao bernardo do campo
Offline

louds wrote:O problema não é o excesso de objetos criados, mas sim quantos você mantem ao mesmo tempo em memória.

Esse teu result-set vem com 500mil registros de uma vez só? O driver faz paginaçã ou coloca tudo em memória de uma única vez?


Tudo de uma vez ele retorna. Mas o problema é que ele tá retornando os registros, é no momento que eu jogo eles para o arquivo que estoura a memória.

Edit: Dúvida besta, se eu paginar isso, na execução ele por exemplo retorna 200 mil registros, quando eu retornar o restante da paginação ele não ocuparia mais espaço em memória? Ou ele vai sobrepor o resultado anterior?

------------------------------------------------------------------
"Think different? I'd be happy if most people would just think..."

http://www.yaw.com.br
http://twitter.com/rafanunes
http://twitter.com/youandwe
[Email]
okara
JavaTeenager

Membro desde: 16/05/2005 08:47:08
Mensagens: 152
Offline

Você está indicando que arquivo é para append na abertura ?


O segundo parâmetro indica que é para append.
louds
Moderador
[Avatar]

Membro desde: 29/04/2003 23:09:15
Mensagens: 4061
Localização: São Paulo
Offline

Rafael Nunes wrote:
Tudo de uma vez ele retorna. Mas o problema é que ele tá retornando os registros, é no momento que eu jogo eles para o arquivo que estoura a memória.


Sim, vai ser mesmo quando você ler o resultset que vai explodir tudo, já que ele vai manter os 500mil em memória. Meio obvio isso.

O problema não é com a parte de I/O do java, pq tem código meu fazendo multiway-merge com arquivos de vários gigas e nem precisa de -Xmx para executar.

http://www.kumpera.net/blog/
http://www.mono-project.com/
"Each individual should work for himself. People will not sacrifice themselves for the company. They come to work at the company to enjoy themselves."
Soichiro Honda
[ICQ]
Rafael Nunes
Moderador
[Avatar]

Membro desde: 09/10/2003 13:41:06
Mensagens: 2890
Localização: sao bernardo do campo
Offline

louds wrote:Sim, vai ser mesmo quando você ler o resultset que vai explodir tudo, já que ele vai manter os 500mil em memória. Meio obvio isso.


Taí algo que eu não sabia, que só no primeiro acesso que ele 'explode', mas bem estranho é que debugando aqui, ele estoura a memória no meio da gravação de dados, depois de gravar uma boa parte.
Vou tentar usar o Resulset direto mesmo ver que zica dá.

------------------------------------------------------------------
"Think different? I'd be happy if most people would just think..."

http://www.yaw.com.br
http://twitter.com/rafanunes
http://twitter.com/youandwe
[Email]
thingol
Moderador

Membro desde: 29/07/2004 16:10:13
Mensagens: 17543
Offline

Se não me engano, quando você cria um BufferedWriter, são alocados apenas 8KB para um buffer interno (você pode usar um segundo parâmetro que possibilita especificar um buffer maior.)

Então não é o problema do BufferedWriter, e sim de sua consulta.

(Se você usar a consulta de modo que os dados não sejam retidos na memória, ou seja, abrir um Forward-Only Cursor, então não deveria haver problemas).

Uma forma de você ver que troço está gastando memória é rodar seu programa com o Mustang e usar o programa jmap com a opção -dump, e usar o jhat para mostrar (usando uma interface web bem simples) quais são os objetos que ocupam mais memória. Mas pelo jeito é só alterar o jeito de você abrir seu ResultSet.
[WWW]
okara
JavaTeenager

Membro desde: 16/05/2005 08:47:08
Mensagens: 152
Offline

tente usar a propriedade setFetchSize(int rows) do resultset.
 
Índice dos Fóruns » Java Básico
Ir para:   
Powered by JForum 2.1.8 © JForum Team