views:

797

answers:

3

I am working on a basic Struts based application that is experience major spikes in memory. We have a monitoring tool that will notice one request per user adding 3MB to the JVM heap memory. Are there any tips to encourage earlier garbage collection, free up memory or improve performance?

The application is a basic Struts application but there are a lot of rows in the JSP report, so there may be a lot of objects created. But it isn't stuff you haven't seen before.

  1. Perform a set of database query.
  2. Create an serialized POJO object bean. This represents a row.
  3. Add a row to an array list.
  4. Set the array list to the form object when the action is invoked.
  5. The JSP logic will iterate through the list from the ActionForm and the data is displayed to the user.

Notes:
1. The form is in session scope and possibly that array list of data (maybe this is an issue).
2. The POJO bean contains 20 or so fields, a mix of String or BigDecimal data.

The report can have 300 to 1200 or so rows. So there are at least that many objects created.

A: 

Given the information you provide, I'd estimate that you're typically loading 1 to 2 megabytes of data for a result: 750 rows * 20 fields * 100 bytes per field = 1.4 Mb. Now consider all of the temporary objects needed between the database and the final markup. 3 Mb isn't surprising.

I'd only be concerned if that memory seems to have leaked; i.e., the next garbage collection of the young generation space doesn't collect all of those objects.

erickson
A: 
  1. List item

When desiging reports to be rendered in web application, consider the number of records fetched from database.

If the number of records is high and the overall recordset is taking lot of memory, then consider using pagination of report.

As far as possible donot invoke garbage collector explicitly. This is so because of two reasons:

  1. Garbage collection is costly process as it scans whole of the memory.

  2. Most of the production servers would be tuned at JVM level to avoid explicit garabage collection

A: 

I believe the problem is the arraylist in the ActionForm that needs to allocate a huge chunk of memory space. I would write the query results directly to the response: read the row from the resultset, write to response, read next row, write etc. Maybe it's not MVC but it would be better for your heap :-)

ActionForms are fine for CRUD operations, but for reports ... I don't think so.

Note: if the ActionForm has scope=session the instance will be alive (along with the huge arraylist) until session expires. If scope=request the instance will be available for the GC.

Lluis Martinez