Memory Leak

Stimulsoft Reports.NET discussion
Post Reply
fphealthcare
Posts: 33
Joined: Sun Jul 02, 2006 6:06 pm
Location: New Zealand

Memory Leak

Post by fphealthcare »

We have an application with a database of users. You can select a user then generate a report for the selected user. The report is shown onscreen (using report.Show(true)). After the report is shown the you can print/save/email the report, then you can close the report, go back to the application, choose another user, and generate the report again etc etc.

We find that everytime we generate another report the memory usage goes up. Sometimes by 30mb, sometimes by only 10mb, but it always goes up. This is both virtual memory and physical memory. After many times of doing this we managed to get the memory usage to 2gb (both virtual and physical), then we'd get strange errors.

We feel we may not be creating reports in the most efficient way. Here is how we create the reports.

1. Report object is created - we have a wrapper class for the report
2. Report file is loaded using report.Load(filename)
3. Register data to report by using report.RegData(name, dataset)
4. Shows the report by using report.Show(true)
When the report is closed, another use can be selected and steps 3 and 4 are executed again. This happens every time a new user is selected.

Are we doing something wrong? Or is there a better way of using the report?

Thanks
Vital
Posts: 1278
Joined: Fri Jun 09, 2006 4:04 am

Memory Leak

Post by Vital »

You can solve this problems. I would like to describe some principles of the functioning of StimulReport.Net.

1. Source code of the report is formed. Forming is based on the grounds of meta description of the report
2. This source code is compiled to assembly
3. Assembly is loaded to memory
4. Create object of the report from loaded assemblies
5. Report is rendered
6. Report is showed

The loaded assembly occupies place in memories. If to produce compiling the report ten times,
then the assembly of the report will be ten times created and loaded in memory. How to correct it?
Regrettably .Net Framework does not give the possibility to unload the assembly from memory
(only together with application domain, but this method has much restrictions).

1. Save the report as class and add it to project. In this case compiling occurs
together with project.
2. Save the report as assembly. Before building of the report its necessary to load
from assembly with the StiReport.GetReportFromAssembly method.

Method has two variants of the work:

1.
Code:

Code: Select all

StiReport report = StiReport.GetReportFromAssembly("myreport.dll");

Report will be loaded in memory exactly as many times as the method will be called,
but the file of the assembly of the report will not be locked.

2.
Code:

Code: Select all

StiReport report = StiReport.GetReportFromAssembly("myreport.dll", true);

Report will be loaded in memory only once even though the method is called over and over again.
At file of the assembly will be locked before closing of application (blocking leaves only after
closing of application). Use of this method does not cause the memory leaks since assembly
of the report is loaded in memory only once.

Loading the reports from assemblies has one unpleasant minus - it is necessary beforehand to
prepare the assemblies of the reports. But minus possible easy avoid. Idea is concluded in that
to produce compiling report under the first start the report on building:

1. Check, there is file of the compiled report on disk?
2. If file there is, that loads report from assembly and start on execution
3. File does not exist, then compile the report in to file (compiling will is made in any cases)
and start the report on execution.

Under following start the report on execution he will is loaded from file. Example of the code:

Code:

Code: Select all

StiReport report = null;
                    
string compiledReportFile = "report.dll";

if (File.Exists(compiledReportFile))
{
report = StiReport.GetReportFromAssembly(compiledReportFile, true);
    report.RegData(“MyData”, dataSet);
    report.Render();
}
else
{
    report = new StiReport();
    report.Load(file);
        
    report.RegData(“MyData”, dataSet);
                                        
        report.Compile(compiledReportFile);                        
            
    report.Render();
}
Note: If report is loaded from assembly, that speeds up the building of the reports
much above since compiling is not required.

About data. If object of the report exists in memory long time, that necessary to clean
the references to data after building of the report is finished:

Code:

Code: Select all

Report.Dictionary.DataStore.Clear();

If report was compiled, that in addition:

Code:

Code: Select all

Report.CompiledReport.DataStore.Clear();

Thanks.
Post Reply