I'm doing a web application that has a finite recursive loop. But during the process memory consumption is constantly increasing and in the end Visual Studio has more than 2 Gigabytes of memory usage.
I'd like to know some concepts about memory allocation and deallocation (if that's what those terms are) and what can cause that huge consumption, or what artifacts can I use to free memory.
I'm not very experienced and I believe this may be caused by non-optimized (not to say bad) codes. Here is 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