Утечка в неуправляемой куче
Добавлено: 09 дек 2014, 16:33
Здравствуйте!
Не однократно поднимал вопрос по поводу расходования ОЗУ при построении отчетов. Использовал статьи приведенные на этом форуме, а так же три части статей по оптимизации отчетов. Но сегодня вскрылась одна особенность.
Есть код класса, реализующий работу со списком отчетов.
Метод ProcessReportBeforeUsage вызывается каждый раз, когда необходимо отрисовать отчет. К сведению, отчет представляет из себя один БЛАНК состоящий из 4-х страниц. То есть может быть цикл из 1000-100 000 итераций, и за каждую итерацию нужно отрисовать один БЛАНК и сохранять в файл.
Обнаружено, что после первых двух итераций(если убрать комментарии в указанном методе) в отчетах перестает отображаться статичная картинка(к примеру герб печати на одной из страниц), в то время как динамичные картинки(берущиеся из БД) отображаются корректно.
Если добавить закомментировать условие if (!mLoadedFromAssembly), которое в примере уже реализовано, то отчеты отображаются правильно, но происходит утечка памяти, и примерно уже к 1000 итерации выдается исключение OutOfMemory (размер достигает 1 ГБайт).
Получается, с комментариями код похож на тот, который рекомендуют здесь на форуме(то есть если первого прохода и сохранения в сборку каждый раз при отрисовке подгружать отчет из сохраненной сборки), а если с моей доработкой(после сохранения в сборку и однократной загрузки из нее) то пропадает изображение.
Утечку искал при помощи системного монитора и ссылки http://msdn.microsoft.com/ru-ru/magazine/cc163491.aspx
Прошу помощи!
Не однократно поднимал вопрос по поводу расходования ОЗУ при построении отчетов. Использовал статьи приведенные на этом форуме, а так же три части статей по оптимизации отчетов. Но сегодня вскрылась одна особенность.
Есть код класса, реализующий работу со списком отчетов.
Код: Выделить всё
public class RegisteredReport
{
public Stimulsoft.Report.StiReport mReport;
public String mName;
public String mReportCacheCompiledFolderName;
public String mReportCacheCompiledFileName;
public String mViolationTypes;
public String mOriginalFoto;
public DateTime mDateFrom;
public DateTime mDateTo;
public bool mLoadedFromAssembly = false;
public int mCollate;
public RegisteredReport(Stimulsoft.Report.StiReport report, String name, String violationTypes, String originalFoto, DateTime dateFrom, DateTime dateTo, int collate)
{
mReportCacheCompiledFolderName = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
mReportCacheCompiledFolderName = Path.Combine(mReportCacheCompiledFolderName, "Stimulsoft\\CompiledReports");
mReportCacheCompiledFolderName = Path.Combine(mReportCacheCompiledFolderName, System.Runtime.InteropServices.RuntimeEnvironment.GetSystemVersion().ToString());
mReportCacheCompiledFileName = Path.Combine(mReportCacheCompiledFolderName, report.GetReportAssemblyCacheName());
if (File.Exists(mReportCacheCompiledFileName))
{
File.Delete(mReportCacheCompiledFileName);
}
mReport = report;
mName = name;
mViolationTypes = violationTypes;
mOriginalFoto = originalFoto;
mDateFrom = dateFrom;
mDateTo = dateTo;
mCollate = collate;
}
public void ProcessReportBeforeUsage(DataTable Table)
{
if (File.Exists(mReportCacheCompiledFileName))
{
// if (!mLoadedFromAssembly)
//{
mReport.Dictionary.Clear();
//mReport.CompiledReport.DataStore.Clear();
mReport.Dispose();
mReport =
Stimulsoft.Report.StiReport.GetReportFromAssembly(
mReportCacheCompiledFileName, false);
mLoadedFromAssembly = true;
//}
}
else //Compiled report does not exist
{
mReport.RegData(Table);
if (!Directory.Exists(mReportCacheCompiledFolderName))
Directory.CreateDirectory(mReportCacheCompiledFolderName);
mReport.Compile(mReportCacheCompiledFileName);
mReport = mReport.CompiledReport;
}
}
}
Обнаружено, что после первых двух итераций(если убрать комментарии в указанном методе) в отчетах перестает отображаться статичная картинка(к примеру герб печати на одной из страниц), в то время как динамичные картинки(берущиеся из БД) отображаются корректно.
Если добавить закомментировать условие if (!mLoadedFromAssembly), которое в примере уже реализовано, то отчеты отображаются правильно, но происходит утечка памяти, и примерно уже к 1000 итерации выдается исключение OutOfMemory (размер достигает 1 ГБайт).
Получается, с комментариями код похож на тот, который рекомендуют здесь на форуме(то есть если первого прохода и сохранения в сборку каждый раз при отрисовке подгружать отчет из сохраненной сборки), а если с моей доработкой(после сохранения в сборку и однократной загрузки из нее) то пропадает изображение.
Утечку искал при помощи системного монитора и ссылки http://msdn.microsoft.com/ru-ru/magazine/cc163491.aspx
Прошу помощи!