|
Re: Birt Memory Usage [message #889851 is a reply to message #889849] |
Tue, 19 June 2012 22:19 |
|
Are you using the viewer or the report engine?
Jason
On 6/19/2012 6:05 PM, Stacey Hopkins wrote:
> So I have an RCP that makes use of BIRT to generate reports but what I
> am noticing is the significant memory usage. The key problem I have is
> that it does not free up the memory after it has produced the document.
> So on the first run of a BIRT report (producing a PDF file with a table
> and chart) the memory usage goes up by 60 to 70 MB which never then
> frees up after the report has run .... then each time I run the report
> the memory usage increases by 4MB
>
> I've followed the standard tutorials on the web to create the report
> generator so pretty sure I am not doing anything stupid in the code....
> Is this a common issue? Or where can I go to find out more info? Any
> info appreciated!
|
|
|
|
Re: Birt Memory Usage [message #889942 is a reply to message #889939] |
Wed, 20 June 2012 10:36 |
Stacey Hopkins Messages: 34 Registered: March 2012 |
Member |
|
|
To make sure I have not made any rookie mistakes please see main body of code below.... any feedback appreciated!
// Set up engine config ready for engine
EngineConfig engineConfig = new EngineConfig();
engineConfig.setLogConfig("./birtlogs", Level.SEVERE);
// Create a new report engine factory
IReportEngineFactory factory = (IReportEngineFactory)Platform.createFactoryObject
(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
// Create a new report engine
IReportEngine engine = factory.createReportEngine(engineConfig);
engine.changeLogLevel(Level.WARNING);
try {
// Set up the report design, attached to the report engine
IReportRunnable reportDesign = engine.openReportDesign(rptDesignPath);
//Get designhandle
ReportDesignHandle reportDesignHandle = (ReportDesignHandle) reportDesign.getDesignHandle();
ElementFactory designFactory = reportDesignHandle.getElementFactory();
//delete exisiting data source this is to set the correct location as specified by user
for (int i = 0; i < reportDesignHandle.getDataSources().getCount(); i++){
if (reportDesignHandle.getDataSources().get(i).getName().equalsIgnoreCase("Data Source")){
reportDesignHandle.getDataSources().dropAndClear(i);
}
}
// ...and add in the required filename...
OdaDataSourceHandle dsHandle = designFactory.newOdaDataSource("Data Source", "org.eclipse.datatools.enablement.oda.xml");
dsHandle.setProperty("FILELIST", inputFilePath);
//add the new data source to the report
reportDesignHandle.getDataSources().add(dsHandle);
// OK, so now we've reset the data source to point at our XML file,
// we need to reset all the OdaDataSets (straight, not joined ones) to
// use the new data source. It did actually have exactly the same name,
// but when we deleted the source it upset them all and they forgot it.
List<DataSetHandle> dataSets = reportDesignHandle.getAllDataSets();
for (DataSetHandle dSetHandle : dataSets){
if (dSetHandle instanceof OdaDataSetHandle){
dSetHandle.setDataSource("Data Source");
}
}
// Create the task ready for running and rendering the report now
IRunAndRenderTask task = engine.createRunAndRenderTask(reportDesign);
task.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY , RunBirt.class.getClassLoader());
RenderOption options = new RenderOption();
options.setOption(IPDFRenderOption.PDF_HYPHENATION, true);
//run the task
options.setOutputFileName(outputFilePath);
//set the output format
//but postscript does not follow
//the same as the others so have to change this.
if (mimeConstantSelected.equalsIgnoreCase("ps")){
options.setOutputFormat("postscript");
} else {
options.setOutputFormat(mimeConstantSelected);
}
//set the render options
task.setRenderOption(options);
//run the task
task.run();
//if errors in task
if (task.getErrors().size() > 0) {
MessageDialog.openError(null, "BIRT", task.getErrors().toString());
}
//tidy
task.close();
engine.destroy();
} catch(Exception e){
//tidy up
engine.destroy();
//throw error
throw new Exception(e.getMessage());
}
|
|
|
Re: Birt Memory Usage [message #890068 is a reply to message #889942] |
Wed, 20 June 2012 21:47 |
|
Stacey
Are you stopping and starting the report engine for every report
iteration? If so that should not be done. Create one report engine for
the life of your application and use it to create task for each report
generation/render operation. Wrap the creation of the engine in a
singleton. Take a look at the BirtEngine class example here:
http://wiki.eclipse.org/Servlet_Example_%28BIRT%29_2.1
The example is older but revised copies are listed below and not much
changed with 3.7 API with the exception of setting birt home.
Jason
On 6/20/2012 6:36 AM, Stacey Hopkins wrote:
> To make sure I have not made any rookie mistakes please see main body of
> code below.... any feedback appreciated!
>
> // Set up engine config ready for engine
> EngineConfig engineConfig = new EngineConfig();
> engineConfig.setLogConfig("./birtlogs", Level.SEVERE);
>
> // Create a new report engine factory
> IReportEngineFactory factory =
> (IReportEngineFactory)Platform.createFactoryObject
>
> (IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
>
> // Create a new report engine
> IReportEngine engine = factory.createReportEngine(engineConfig);
> engine.changeLogLevel(Level.WARNING);
>
> try {
> // Set up the report design, attached to the report engine
> IReportRunnable reportDesign =
> engine.openReportDesign(rptDesignPath);
> //Get designhandle
> ReportDesignHandle reportDesignHandle =
> (ReportDesignHandle) reportDesign.getDesignHandle();
> ElementFactory designFactory =
> reportDesignHandle.getElementFactory();
>
> //delete exisiting data source this is to set the correct
> location as specified by user
> for (int i = 0; i <
> reportDesignHandle.getDataSources().getCount(); i++){
> if
> (reportDesignHandle.getDataSources().get(i).getName().equalsIgnoreCase("Data
> Source")){
> reportDesignHandle.getDataSources().dropAndClear(i);
> }
> }
>
> // ...and add in the required filename...
> OdaDataSourceHandle dsHandle =
> designFactory.newOdaDataSource("Data Source",
> "org.eclipse.datatools.enablement.oda.xml");
> dsHandle.setProperty("FILELIST", inputFilePath);
>
> //add the new data source to the report
> reportDesignHandle.getDataSources().add(dsHandle);
>
> // OK, so now we've reset the data source to point at our
> XML file,
> // we need to reset all the OdaDataSets (straight, not
> joined ones) to
> // use the new data source. It did actually have exactly
> the same name,
> // but when we deleted the source it upset them all and
> they forgot it.
> List<DataSetHandle> dataSets =
> reportDesignHandle.getAllDataSets();
> for (DataSetHandle dSetHandle : dataSets){
> if (dSetHandle instanceof OdaDataSetHandle){
> dSetHandle.setDataSource("Data Source");
> }
> }
>
> // Create the task ready for running and rendering the
> report now
> IRunAndRenderTask task =
> engine.createRunAndRenderTask(reportDesign);
>
> task.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY ,
> RunBirt.class.getClassLoader());
>
> RenderOption options = new RenderOption();
> options.setOption(IPDFRenderOption.PDF_HYPHENATION, true);
>
> //run the task
> options.setOutputFileName(outputFilePath);
>
> //set the output format
> //but postscript does not follow
> //the same as the others so have to change this.
> if (mimeConstantSelected.equalsIgnoreCase("ps")){
> options.setOutputFormat("postscript");
> } else {
> options.setOutputFormat(mimeConstantSelected);
> }
>
> //set the render options
> task.setRenderOption(options);
>
> //run the task
> task.run();
>
> //if errors in task
> if (task.getErrors().size() > 0) {
> MessageDialog.openError(null, "BIRT",
> task.getErrors().toString());
> }
>
>
> //tidy
> task.close();
> engine.destroy();
>
> } catch(Exception e){
> //tidy up
> engine.destroy();
> //throw error
> throw new Exception(e.getMessage());
> }
>
>
|
|
|
|
Re: Birt Memory Usage [message #890310 is a reply to message #890165] |
Thu, 21 June 2012 20:36 |
|
The engine destroy should free up the resources. You may want to take a
look at this bugzilla entry:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=351052
What version of BIRT are you using?
Jason
On 6/21/2012 6:50 AM, Stacey Hopkins wrote:
> Thanks for the tip and will follow this design. My application is not
> solely about reporting and the user might not even chose to perform this
> task when using the application. I can see how I could only load the
> engine when the user asks for report generation and then keep this alive
> for the lifetime of the application.
> It just seems a little unfair on system resources. I've done my
> reporting and finished with it so I want give back the memory allocation
> to the computer so it can be used by other applications.
> What is engine.destroy doing? I assumed that when this command is issued
> this would free up this memory allocation i.e. at some point the java
> garbage collector would come along and tidy up.
>
> .... The other issue I have is that the memory usage keeps creeping up
> every time I run a report (see first post ... "then each time I run the
> report the memory usage increases by 4MB")......... I'm concerned that
> eventually I will hit the memory allocation limit?
>
> Stacey
>
|
|
|
|
Re: Birt Memory Usage [message #890588 is a reply to message #890490] |
Fri, 22 June 2012 15:56 |
|
Can you try creating just the once instance of the engine and verify
that are seeing memory continue to grow?
Jason
On 6/22/2012 8:18 AM, Stacey Hopkins wrote:
> 3.7.2
|
|
|
Re: Birt Memory Usage [message #892508 is a reply to message #889849] |
Thu, 28 June 2012 13:42 |
Stacey Hopkins Messages: 34 Registered: March 2012 |
Member |
|
|
Sorry for the late response....work got in the way
So I have wrapped up the create engine code as suggested in a "birt singleton" ...
// Set up engine config ready for engine
> EngineConfig engineConfig = new EngineConfig();
> engineConfig.setLogConfig("./birtlogs", Level.SEVERE);
>
> // Create a new report engine factory
> IReportEngineFactory factory =
> (IReportEngineFactory)Platform.createFactoryObject
>
> (IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
>
> // Create a new report engine
> IReportEngine engine = factory.createReportEngine(engineConfig);
> engine.changeLogLevel(Level.WARNING);
but still no luck.... everytime I run a report which contains a chart (pdf,doc) the memory usage creaps up by about 3 to 4 MB...... it is important to note if I run a report that does not have a chart in it I do not get this increase on each run.
Thanks,
Stacey.
(My junit tests are running faster ... so least thats a good result!)
[Updated on: Thu, 28 June 2012 14:25] Report message to a moderator
|
|
|
Powered by
FUDForum. Page generated in 0.08826 seconds