CrossTab System.OutOfMemory
CrossTab System.OutOfMemory
Добрый день!
Столкнулись с проблемой больших данных в кростабе.
Суть проблемы: запускаем отчёт - получается System.OutOfMemory. Если не получаем в первый раз, то при втором запуске 100%.
Конкретно наш пример во вложении с данными. Данные выбраны из базы с 01.04.2015 по 22.04.2015. Однако, пользователям необходимо выбирать данные за несколько месяцев. В результате на данный момент пользователи не могут вывести необходимые данные.
Версия Стимула 2012.1.1300.0. Но не спешите рекомендовать последнюю версию, мы пробовали запускать на 2014.3.0.0, - результат тот же.
Столкнулись с проблемой больших данных в кростабе.
Суть проблемы: запускаем отчёт - получается System.OutOfMemory. Если не получаем в первый раз, то при втором запуске 100%.
Конкретно наш пример во вложении с данными. Данные выбраны из базы с 01.04.2015 по 22.04.2015. Однако, пользователям необходимо выбирать данные за несколько месяцев. В результате на данный момент пользователи не могут вывести необходимые данные.
Версия Стимула 2012.1.1300.0. Но не спешите рекомендовать последнюю версию, мы пробовали запускать на 2014.3.0.0, - результат тот же.
- Вложения
-
- test_report.7z
- (896.11 КБ) 328 скачиваний
Re: CrossTab System.OutOfMemory
Здравствуйте.
Ваш отчёт с присланными данными строится бел ошибок. Нам необходима дополнительная информация. Как загружается отчёт, как строится первый и второй раз.
Пришлите, пожалуйста, простой проект, который воспроизводит вашу ситуацию.
Спасибо.
Ваш отчёт с присланными данными строится бел ошибок. Нам необходима дополнительная информация. Как загружается отчёт, как строится первый и второй раз.
Пришлите, пожалуйста, простой проект, который воспроизводит вашу ситуацию.
Спасибо.
Re: CrossTab System.OutOfMemory
Добрый день!
Очень просто, возьмите редактор "C:\Program Files\Stimulsoft Reports.Net 2014.3\Bin\Designer.exe", откройте "Отчёт.mrt", загрузите "data.xml", нажмите Preview. Всё работает, да, но это первый раз. Теперь перейдите на Вкладку Page1, и теперь снова запустите отчёт, нажав Preview - у нас выдаёт OutOfMemory уже на второй раз. А если данных больше (скажем, взять data.xml из архива, и скопировать все её строки, чтобы данных стало в два раза больше), то и на первый.
Мы провели дополнительные тесты. И вот, что выяснили. При использовании метода Render() в SDI приложении (на тестовом примере) - всё работает, однако в MDI приложении не работает.
Код тестового приложения, в котором работает:
Этот же код, но в MDI приложении почему-то не работает, тоже выдаёт OutOfMemory. Оговорюсь, что проводили тесты на i7 с 18 Gb RAM, так что памяти навалом, а data.xml всего 44 Mb.
Очень просто, возьмите редактор "C:\Program Files\Stimulsoft Reports.Net 2014.3\Bin\Designer.exe", откройте "Отчёт.mrt", загрузите "data.xml", нажмите Preview. Всё работает, да, но это первый раз. Теперь перейдите на Вкладку Page1, и теперь снова запустите отчёт, нажав Preview - у нас выдаёт OutOfMemory уже на второй раз. А если данных больше (скажем, взять data.xml из архива, и скопировать все её строки, чтобы данных стало в два раза больше), то и на первый.
Мы провели дополнительные тесты. И вот, что выяснили. При использовании метода Render() в SDI приложении (на тестовом примере) - всё работает, однако в MDI приложении не работает.
Код тестового приложения, в котором работает:
Код: Выделить всё
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Stimulsoft.Report;
namespace StiCrossTabTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// stimul objects
private Stimulsoft.Report.StiReport stiReport = null;
private Stimulsoft.Report.Viewer.StiViewerControl stiPreview = null; // public, to change properties in needed reports
DataSet dsData = new DataSet();
DataTable dtData = new DataTable("qrMain");
private void button1_Click(object sender, EventArgs e)
{
button1.Hide();
if (stiReport == null)
{
stiReport = new StiReport();
stiPreview = new Stimulsoft.Report.Viewer.StiViewerControl()
{
Dock = DockStyle.Fill,
Visible = true
};
// preview control events
stiPreview.Close += new EventHandler(stiPreview_Close); // handle Close button event
// assign report object to preview control
stiPreview.Report = stiReport;
stiPreview.FirstPage();
stiPreview.SetZoom(100);
stiReport.PreviewSettings = (int)stiPreview.PreviewSettings; // здесь этот код работает, т.к. стоит до медода .Render()
// assign report object to preview control //
stiPreview.Report = stiReport; // set report object for preview control (each time to refresh the view)
stiPreview.Visible = true; // make preview control visible
stiPreview.FirstPage(); // set report to the first page
stiPreview.SetZoom(100); // set it 100 percent
// add viewer to the form
this.Controls.Add(stiPreview);
}
stiReport.Load("Отчёт.mrt"); // load report each time (just like we get it from Oracle blob)
dsData.ReadXml("data.xml"); // load data each time (just like we get it from Oracle data)
stiReport.RegData(dsData);
stiReport.Dictionary.Synchronize();
stiReport.Render();
}
// close button of the preview control
private void stiPreview_Close(object sender, EventArgs e)
{
if (!button1.Visible)
button1.Show();
}
}
}
Re: CrossTab System.OutOfMemory
Добрый день!
Сгенерировал тестовый проект с данными. На форме кнопка "Run", если её нажать, загрузится xml с данными, выведет отчёт. Потом надо нажать Close в очёте, появится снова кнопка "Run", нажать её ещё раз, - в этот раз на методе .Render() будет Exception.
Собственно, если данных будет больше, Exception будет и в первый раз.
Сгенерировал тестовый проект с данными. На форме кнопка "Run", если её нажать, загрузится xml с данными, выведет отчёт. Потом надо нажать Close в очёте, появится снова кнопка "Run", нажать её ещё раз, - в этот раз на методе .Render() будет Exception.
Собственно, если данных будет больше, Exception будет и в первый раз.
- Вложения
-
- StiCrossTabTest2.7z
- (795.84 КБ) 344 скачивания
Re: CrossTab System.OutOfMemory
Здравствуйте.
Вы нам прислали SDI проект. Мы не можем на нём воспроизвести проблему.
С присланным отчётом проект вообще отказался работать, тестировали с предыдущим.
Пришлите, пожалуйста, рабочий проект, который воспроизводит проблему.
Спасибо.
Вы нам прислали SDI проект. Мы не можем на нём воспроизвести проблему.
С присланным отчётом проект вообще отказался работать, тестировали с предыдущим.
Пришлите, пожалуйста, рабочий проект, который воспроизводит проблему.
Спасибо.
Re: CrossTab System.OutOfMemory
Доброе утро!
Да, верно, это SDI приложение, т.к. мы не можем в точности воспроизвести вам пример MDI приложения, т.к. оно технически сложное и использует сторонние компоненты.
Однако, мы провели дополнительные тесты, и удалось получить тот же Exception на отдельном простейшем SDI приложении (см. вложение).
Суть та же: компилируем, запускаем файл StiCrossTabTest.exe, он загружает отчёт "data.mrt", и словарь "Dictionary Designer.dct" (ссылается на "data.xml" и "schema.xsd").
На форме нажимаем "Run", ждём пока сформируются 77 страниц.
Теперь жмём "Close" в самом отчёте, появится кнопка "Run", нажимаем её ещё раз, - в этот раз получаем System.OutOfMemory:
---
----------------------------
[Customer Explanation]
----------------------------
[General Info]
Application: StiCrossTabTest
Framework: v4.0.30319
Version: Version: 2014.3.0 from 1 December 2014
MachineName: VS-LEON-PROGRAM
OSVersion: Microsoft Windows NT 6.1.7600.0
UserName: leon
----------------------------
[Exception Info]
Message: Exception of type 'System.OutOfMemoryException' was thrown.
Source: mscorlib
StackTrace:
at System.Object.MemberwiseClone()
at Stimulsoft.Base.Services.StiService.Clone()
at Stimulsoft.Report.Components.StiComponent.Clone(Boolean cloneProperties)
at Stimulsoft.Report.Components.StiSimpleText.Clone(Boolean cloneProperties)
at Stimulsoft.Report.Components.StiText.Clone(Boolean cloneProperties)
at Stimulsoft.Report.CrossTab.StiCrossSummary.Clone(Boolean cloneProperties)
at Stimulsoft.Report.Components.StiComponent.Clone()
at Stimulsoft.Report.CrossTab.Core.StiGrid.SetCell(Int32 cellX, Int32 cellY, Int32 cellWidth, Int32 cellHeight, Object text, Object value, StiCrossField field, Boolean isNumeric, Object hyperlink, Object toolTip, Object tag, Dictionary`2 drillDownParameters, Int32 level)
at Stimulsoft.Report.CrossTab.Core.StiGrid.SetCell(Int32 cellX, Int32 cellY, Int32 cellWidth, Int32 cellHeight, Object text, Object value, StiCrossField field, Boolean isNumeric, Object hyperlink, Object toolTip, Object tag, Dictionary`2 drillDownParameters)
at Stimulsoft.Report.CrossTab.Core.StiCross.SetCellValue(Int32 x, Int32 y, Object value, Int32 calcIndex, Int32 level, StiFieldType fieldType, Object hyperlinkValue, Object toolTipValue, Object tagValue, Dictionary`2 drillDownParameters)
at Stimulsoft.Report.CrossTab.Core.StiCross.CopySummary(StiSummary summary, Int32 left, Int32 top, Int32 colIndex, Int32 rowIndex, Boolean setValue, Boolean grandTotal, Object emptyValue)
at Stimulsoft.Report.CrossTab.Core.StiCross.CopySummaries(Int32 left, Int32 top, Object emptyValue)
at Stimulsoft.Report.CrossTab.Core.StiCross.Create(DataTable table, StiReport report, StiSummaryDirection direction, String emptyValue)
at Stimulsoft.Report.CrossTab.StiCrossTabHelper.BuildCross(StiCrossTab masterCrossTab, Boolean designTime)
at Stimulsoft.Report.CrossTab.StiCrossTabHelper.CreateCross(StiCrossTab masterCrossTab)
at Stimulsoft.Report.Engine.StiPageHelper.RenderPage(StiPage page)
at Stimulsoft.Report.Engine.StiRenderProviderV2.RenderReport(StiReport report, StiReport masterReport, StiRenderState state)
at Stimulsoft.Report.Engine.StiRenderProviderV2.Render(StiReport report, StiRenderState state)
at Stimulsoft.Report.Engine.StiReportV2Builder.RenderSingleReport(StiReport masterReport, StiRenderState renderState)
at Stimulsoft.Report.StiReport.RenderReport(StiRenderState renderState)
at Stimulsoft.Report.StiReport.Render(StiRenderState renderState, StiGuiMode guiMode)
at Stimulsoft.Report.StiReport.Render(StiRenderState renderState)
at Stimulsoft.Report.StiReport.Render(Boolean showProgress, Int32 fromPage, Int32 toPage)
at Stimulsoft.Report.StiReport.Render(Boolean showProgress)
at Stimulsoft.Report.Design.Controls.StiDesignerPreviewControl.btRefresh_Click(Object sender, EventArgs e)
----------------------------
[Assemblies]
mscorlib, Version = 4.0.0.0
Oracle.DataAccess, Version = 2.112.1.0
Stimulsoft.Report, Version = 2014.3.0.0
Stimulsoft.Report.Win, Version = 2014.3.0.0
System, Version = 4.0.0.0
System.Data, Version = 4.0.0.0
System.Drawing, Version = 4.0.0.0
System.Windows.Forms, Version = 4.0.0.0
---
Да, верно, это SDI приложение, т.к. мы не можем в точности воспроизвести вам пример MDI приложения, т.к. оно технически сложное и использует сторонние компоненты.
Однако, мы провели дополнительные тесты, и удалось получить тот же Exception на отдельном простейшем SDI приложении (см. вложение).
Суть та же: компилируем, запускаем файл StiCrossTabTest.exe, он загружает отчёт "data.mrt", и словарь "Dictionary Designer.dct" (ссылается на "data.xml" и "schema.xsd").
На форме нажимаем "Run", ждём пока сформируются 77 страниц.
Теперь жмём "Close" в самом отчёте, появится кнопка "Run", нажимаем её ещё раз, - в этот раз получаем System.OutOfMemory:
---
----------------------------
[Customer Explanation]
----------------------------
[General Info]
Application: StiCrossTabTest
Framework: v4.0.30319
Version: Version: 2014.3.0 from 1 December 2014
MachineName: VS-LEON-PROGRAM
OSVersion: Microsoft Windows NT 6.1.7600.0
UserName: leon
----------------------------
[Exception Info]
Message: Exception of type 'System.OutOfMemoryException' was thrown.
Source: mscorlib
StackTrace:
at System.Object.MemberwiseClone()
at Stimulsoft.Base.Services.StiService.Clone()
at Stimulsoft.Report.Components.StiComponent.Clone(Boolean cloneProperties)
at Stimulsoft.Report.Components.StiSimpleText.Clone(Boolean cloneProperties)
at Stimulsoft.Report.Components.StiText.Clone(Boolean cloneProperties)
at Stimulsoft.Report.CrossTab.StiCrossSummary.Clone(Boolean cloneProperties)
at Stimulsoft.Report.Components.StiComponent.Clone()
at Stimulsoft.Report.CrossTab.Core.StiGrid.SetCell(Int32 cellX, Int32 cellY, Int32 cellWidth, Int32 cellHeight, Object text, Object value, StiCrossField field, Boolean isNumeric, Object hyperlink, Object toolTip, Object tag, Dictionary`2 drillDownParameters, Int32 level)
at Stimulsoft.Report.CrossTab.Core.StiGrid.SetCell(Int32 cellX, Int32 cellY, Int32 cellWidth, Int32 cellHeight, Object text, Object value, StiCrossField field, Boolean isNumeric, Object hyperlink, Object toolTip, Object tag, Dictionary`2 drillDownParameters)
at Stimulsoft.Report.CrossTab.Core.StiCross.SetCellValue(Int32 x, Int32 y, Object value, Int32 calcIndex, Int32 level, StiFieldType fieldType, Object hyperlinkValue, Object toolTipValue, Object tagValue, Dictionary`2 drillDownParameters)
at Stimulsoft.Report.CrossTab.Core.StiCross.CopySummary(StiSummary summary, Int32 left, Int32 top, Int32 colIndex, Int32 rowIndex, Boolean setValue, Boolean grandTotal, Object emptyValue)
at Stimulsoft.Report.CrossTab.Core.StiCross.CopySummaries(Int32 left, Int32 top, Object emptyValue)
at Stimulsoft.Report.CrossTab.Core.StiCross.Create(DataTable table, StiReport report, StiSummaryDirection direction, String emptyValue)
at Stimulsoft.Report.CrossTab.StiCrossTabHelper.BuildCross(StiCrossTab masterCrossTab, Boolean designTime)
at Stimulsoft.Report.CrossTab.StiCrossTabHelper.CreateCross(StiCrossTab masterCrossTab)
at Stimulsoft.Report.Engine.StiPageHelper.RenderPage(StiPage page)
at Stimulsoft.Report.Engine.StiRenderProviderV2.RenderReport(StiReport report, StiReport masterReport, StiRenderState state)
at Stimulsoft.Report.Engine.StiRenderProviderV2.Render(StiReport report, StiRenderState state)
at Stimulsoft.Report.Engine.StiReportV2Builder.RenderSingleReport(StiReport masterReport, StiRenderState renderState)
at Stimulsoft.Report.StiReport.RenderReport(StiRenderState renderState)
at Stimulsoft.Report.StiReport.Render(StiRenderState renderState, StiGuiMode guiMode)
at Stimulsoft.Report.StiReport.Render(StiRenderState renderState)
at Stimulsoft.Report.StiReport.Render(Boolean showProgress, Int32 fromPage, Int32 toPage)
at Stimulsoft.Report.StiReport.Render(Boolean showProgress)
at Stimulsoft.Report.Design.Controls.StiDesignerPreviewControl.btRefresh_Click(Object sender, EventArgs e)
----------------------------
[Assemblies]
mscorlib, Version = 4.0.0.0
Oracle.DataAccess, Version = 2.112.1.0
Stimulsoft.Report, Version = 2014.3.0.0
Stimulsoft.Report.Win, Version = 2014.3.0.0
System, Version = 4.0.0.0
System.Data, Version = 4.0.0.0
System.Drawing, Version = 4.0.0.0
System.Windows.Forms, Version = 4.0.0.0
---
- Вложения
-
- exception.png (16.53 КБ) 8614 просмотров
-
- StiCrossTabTest2.7z
- (679.34 КБ) 349 скачиваний
Re: CrossTab System.OutOfMemory
Здравствуйте.
В вашем тестовом проекте Platform target установлен в x86.
Данные занимают в памяти слишком много места. Построенный отчёт ещё больше.
Соответственно, из-за ограничений .Net Framework, вы получаете Out of Memory exception.
Спасибо.
В вашем тестовом проекте Platform target установлен в x86.
Данные занимают в памяти слишком много места. Построенный отчёт ещё больше.
Соответственно, из-за ограничений .Net Framework, вы получаете Out of Memory exception.
Спасибо.
Re: CrossTab System.OutOfMemory
Весь наш проект скомпилирован для x86 (6 филиалов в крупнейших городах РФ), в нашей программе работают сотни людей. На данный момент на x64 мы переходить не планируем, если вы об этом, хотя мне не ясна связь утечки памяти и платформы.
Более того, вы обратили внимание, что отчёт первый раз выполняется нормально, и только на второй раз выдаёт exception.
То есть, иными словами, если бы данных было больше, то отчёт вообще бы не выполнился, и это не проблема платформы, т.к. xml-файл всего 56 Mb.
У нас есть подобные отчёты, в которых нам приходится ограничивать для пользователей интервалы дат до одного года, т.к., если будет большое количество данных, то отчёт с CrossTab'ом так же выдаёт out of memory exception.
Как нам вообще быть в этой ситуации? Ведь мы тестировали на последней версии отчётной системы. На текущий момент пользователи не могут выбрать данные более чем за месяц, а если выводят отчёт (даже с меньшим количеством данных) второй раз, то сразу же получают ошибку, что вызывает всеобщее негодование в сторону IT-отдела.
Посмотрел, в памяти приложение (тестовое, что в предыдущем посте) занимает 1.2 Gb, при втором запуске почти 1.7 Gb, на к примеру, памяти у меня 18 Gb.
Скомпилировал тот же самый тестовый проект под x64, - да, работает, но занимает в памяти уже 3 Gb и больше, а у пользователей как правило стоит 4 Gb.
Пробовал принудительно вызывать Garbage Collector после нажатия кнопки Close, - не помогает.
И мне не ясно, почему в первый раз отчёт рисуется корректно, а второй раз уже не хватает памяти?
Более того, вы обратили внимание, что отчёт первый раз выполняется нормально, и только на второй раз выдаёт exception.
То есть, иными словами, если бы данных было больше, то отчёт вообще бы не выполнился, и это не проблема платформы, т.к. xml-файл всего 56 Mb.
У нас есть подобные отчёты, в которых нам приходится ограничивать для пользователей интервалы дат до одного года, т.к., если будет большое количество данных, то отчёт с CrossTab'ом так же выдаёт out of memory exception.
Как нам вообще быть в этой ситуации? Ведь мы тестировали на последней версии отчётной системы. На текущий момент пользователи не могут выбрать данные более чем за месяц, а если выводят отчёт (даже с меньшим количеством данных) второй раз, то сразу же получают ошибку, что вызывает всеобщее негодование в сторону IT-отдела.
Посмотрел, в памяти приложение (тестовое, что в предыдущем посте) занимает 1.2 Gb, при втором запуске почти 1.7 Gb, на к примеру, памяти у меня 18 Gb.
Скомпилировал тот же самый тестовый проект под x64, - да, работает, но занимает в памяти уже 3 Gb и больше, а у пользователей как правило стоит 4 Gb.
Пробовал принудительно вызывать Garbage Collector после нажатия кнопки Close, - не помогает.
И мне не ясно, почему в первый раз отчёт рисуется корректно, а второй раз уже не хватает памяти?
Re: CrossTab System.OutOfMemory
Здравствуйте, Леонид.
По умолчанию на x86-процесс выделяется не более 2Гб адресного пространства.
Реально же для приложения доступно меньше.
При построении отчёта требуется значительно больше памяти чем размер xml-файла. Даже при загрузке вашей XML(56Мб) в DataSet c помощью метода ReadXml() процесс разрастается на 150Мб.
Для построения такого сложного компонента, как Cross-tab, для расчётов требуется намного больше памяти. Утечки памяти никакой нет. Вы не вызываете метод Dispose() для отчёта и начинаете строить отчёт ещё раз. Естественно, что использование памяти ещё возрастает.
Спасибо.
По умолчанию на x86-процесс выделяется не более 2Гб адресного пространства.
Реально же для приложения доступно меньше.
При построении отчёта требуется значительно больше памяти чем размер xml-файла. Даже при загрузке вашей XML(56Мб) в DataSet c помощью метода ReadXml() процесс разрастается на 150Мб.
Для построения такого сложного компонента, как Cross-tab, для расчётов требуется намного больше памяти. Утечки памяти никакой нет. Вы не вызываете метод Dispose() для отчёта и начинаете строить отчёт ещё раз. Естественно, что использование памяти ещё возрастает.
Спасибо.
Re: CrossTab System.OutOfMemory
. Так и есть. Почему я его должен вызывать, разве у вас есть неуправляемые объекты в коде отчёта?Вы не вызываете метод Dispose()
Хорошо, стал вызывать метод, это разумеется не помогло, т.к. Garbage Collector сразу не подчистит эти объекты. Поэтому стал вызывать в том же простом примере вот так:
Код: Выделить всё
private void stiPreview_Close(object sender, EventArgs e)
{
stiReport.Dispose();
stiReport = null;
stiPreview.Dispose();
stiPreview = null;
// без этих двух строк не будет актуально, т.к. пользователь сразу же запустит отчёт, выбрав другие даты, а память не будет освобождена
GC.WaitForPendingFinalizers();
GC.Collect();
if (!button1.Visible)
button1.Show();
}
И что нам с этим делать в итоге, что сказать десяткам пользователей, которые пользуются отчётом?