11
I’m making a web application that has a finite recursive loop. But during the process the memory consumption is constantly growing and at the end Visual Studio has more than 2 Gigas of memory use.
I would like to know some concepts about memory allocation and displacement (if those are the terms) and what can cause this immense consumption, or what tricks I can turn to for memory release.
I am not very experienced and I believe that this may be caused by not optimized codes (not to say bad ones). Follow my code:
protected void BtnExportar_OnClick(object sender, EventArgs e)
{
string folder = @"D:\Fichas\";
DateTime data = new DateTime();
data = DateTime.Now;
data = data.Date;
string dataSoNumeros = new String(data.ToString().Where(Char.IsDigit).ToArray());
if (!Directory.Exists(folder))
{
Directory.CreateDirectory(folder);
}
if (!Directory.Exists(folder + dataSoNumeros.Substring(0, 8)))
{
Directory.CreateDirectory(folder + dataSoNumeros.Substring(0, 8));
}
Stop = false;
this.IniciarExportacao();
}
public void IniciarExportacao()
{
IList<Ficha> Fichas = null;
do
{
Fichas = this.ObterFichas();
this.GerarArquivo(Fichas);
}
while (Fichas.Count > 0 && Stop == false);
detalhesArquivo.Text = "Exportação Concluída.";
}
public IList<Ficha> ObterFichas()
{
DetachedCriteria criteria = DetachedCriteria.For<Ficha>();
criteria.SetMaxResults(1);
criteria.CreateAlias("exportacao", "e",NHibernate.SqlCommand.JoinType.LeftOuterJoin).Add(Restrictions.IsNull("e.Exportado"));
var fichasObtidas = DomainService.FichaRepository().LoadAll(criteria);
return fichasObtidas;
}
public void GerarArquivo(IList<Ficha> Fichas)
{
msgLog = new StringBuilder();
msgLog_Inicio = " - Iniciando Exportação da Ficha " + Fichas[0].IdFicha + " / Conta " + Fichas[0].Conta.IdConta + "...";
msgLog_Gerando = " - Gerando imagem do arquivo...";
foreach (var index in Fichas)
{
#region DEFAULT
byte[] arqB = null;
string nomarq = "";
string saveLocation = null;
System.Drawing.Image imageArquivo = null;
arqB = index.Arquivo;
nomarq = index.Conta.IdConta + "_" + index.IdFicha;
DateTime data = new DateTime();
data = DateTime.Now;
data = data.Date;
string dataSoNumeros = new String(data.ToString().Where(Char.IsDigit).ToArray());
saveLocation = @"D:\fichas\" + dataSoNumeros.Substring(0, 8) + @"\" + nomarq + ".jpg";
Ficha ficha = new Ficha();
Exportacao fichaExportacao = new Exportacao();
ficha = index;
fichaExportacao.Ficha = index;
fichaExportacao.IdFicha = index.IdFicha;
fichaExportacao.DataExportacao = DateTime.Now;
fichaExportacao.IdUsuarioExportador = ControlUsuario.GetSession.Usuario.IdUsuario;
#endregion
try
{
imageArquivo = this.byteArrayToImage(arqB);
imageArquivo.Save(saveLocation, System.Drawing.Imaging.ImageFormat.Jpeg);
fichaExportacao.Exportado = 1;
msgLog_Imagem = " - Arquivo gerado na pasta "+ saveLocation +"";
}
catch (Exception)
{
fichaExportacao.Exportado = 0;
msgLog_Imagem = " - O arquivo está corrompido e não foi gerado...";
}
msgLog.AppendLine(msgLog_Inicio);
msgLog.AppendLine(msgLog_Gerando);
msgLog.AppendLine(msgLog_Imagem);
this.AtualizarFicha(ficha, fichaExportacao, saveLocation, msgLog);
}
}
public void AtualizarFicha(Ficha ficha, Exportacao fichaExportacao, string saveLocation, StringBuilder msgLog)
{
if (ficha.exportacao == null)
{
try
{
DomainService.ExportacaoRepository().SaveNew(fichaExportacao);
msgLog_Update = " - Atualizando registro no banco de dados...";
msgLog_Usuario = " - Exportação concluída por " + ControlUsuario.GetSession.Usuario.Nome + ".";
}
catch (Exception)
{
msgLog_Update = " - Falha ao atualizar banco de dados...";
msgLog_Usuario = " - Exportação não pôde ser concluída. Exportador: " + ControlUsuario.GetSession.Usuario.Nome + ".";
}
}
else
{
try
{
DomainService.ExportacaoRepository().Update(fichaExportacao);
msgLog_Update = " - Atualizando registro no banco de dados...";
msgLog_Usuario = " - Exportação concluída por " + ControlUsuario.GetSession.Usuario.Nome + ".";
}
catch (Exception)
{
msgLog_Update = " - Falha ao atualizar banco de dados...";
msgLog_Usuario = " - Exportação não pôde ser concluída. Exportador: " + ControlUsuario.GetSession.Usuario.Nome + ".";
}
}
msgLog.AppendLine(msgLog_Update);
msgLog.AppendLine(msgLog_Usuario);
using (StreamWriter w = new StreamWriter(@"D:\fichas\log.txt", true, Encoding.UTF8))
{
Log(msgLog, w);
}
using (StreamReader r = File.OpenText(@"D:\fichas\log.txt"))
{
DumpLog(r);
}
}
#region ARQUIVO IMAGEM
public byte[] Arquivo(object sender, EventArgs e)
{
return base.Cache[base.Request.QueryString["id"]] as byte[];
}
public byte[] imageToByteArray(System.Drawing.Image imageIn)
{
using (var ms = new MemoryStream())
{
imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
return ms.ToArray();
}
}
public System.Drawing.Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
System.Drawing.Image returnImage = System.Drawing.Image.FromStream(ms);
return returnImage;
}
#endregion
#region LOGS
public static void Log(StringBuilder msgLog, TextWriter w)
{
w.WriteLine("[{0} {1}] ---------------------------------------", DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString());
w.WriteLine("{0}", msgLog.ToString());
}
public static void DumpLog(StreamReader r)
{
string line;
while ((line = r.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
#endregion
Can you post the code that is producing this problem? Much better to give accurate advice that solves the problem than to guess possible causes randomly.
– Guilherme Bernal
At first I think it would be more interesting for me (and future readers) to better understand how the "wheel" works. But I will post the code.
– Joao Paulo
Just one possibility: Comment on all the lines you write in the log and try again. You’re keeping the log whole in memory. Any significant changes? Other: what order are we talking about here? Thousands of chips? Millions?
– Guilherme Bernal
21 thousand chips. Each one with an image field registered in the bank.
– Joao Paulo
I did not find any recursion in this code! But it seems that you are putting a lot of images in memory, no?
– bfavaretto
There’s a do/while that repeats 22,000 times. But I think you might be putting the images in memory, yes. I just don’t know how to avoid it, so I figured I’d ask.
– Joao Paulo
The do/while is just a loop, it is not recursion. But what all indicates the problem is even with the images.
– bfavaretto