Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Plug memory leaks in enterprise Java applications

Strategies for detecting and fixing enterprise memory leaks

  • Print
  • Feedback

Page 2 of 7

ResultSet and Statement Objects

The Statement and ResultSet interfaces are used with Java Database Connectivity (JDBC) APIs. Statement/PreparedStatment objects are used for executing a SQL Statement; ResultSet objects are used for storing SQL queries' results.

A Java Enterprise Edition (Java EE) application usually connects to the database by either making a direct connection to the database using JDBC thin drivers provided by the database vendor or creating a pool of database connections within the Java EE container using the JDBC drivers. If the application directly connects to the database, then on calling the close() method on the connection object, the database connection closes and the associated Statement and ResultSet objects close and are garbage collected. If a connection pool is used, a request to the database is made using one of the existing connections in the pool. In this case, on calling close() on the connection object, the database connection returns to the pool. So merely closing the connection does not automatically close the ResultSet and Statement objects. As a result, ResultSet and Statement will not become eligible for garbage collection, as they continue to remain tagged with the database connection in the connection pool.

To investigate the memory leak caused by not closing Statement and ResultSet objects while using a connection pool, I used a sample Java EE application that queries a database table and displays the results in a JSP (JavaServer Pages) page. It also allows you to save records to the database table. The application is deployed in iPlanet App Server 6.0. I used JProbe to analyze the memory utilization by the application.

The sample application uses a database table with the following structure:

 ID   NUMBER
NAME   VARCHAR2(300) 
STREET   VARCHAR(500)
CITY   VARCHAR(500)
STATE   VARCHAR(200)
CREATEDON   DATE
VERSIONNO   NUMBER
DELETESTATUS   NUMBER
UPDATEDBY   VARCHAR(20)
UPDATEDON   DATE 


First, I executed the application with the Statement and ResultSet objects closed. Subsequently, I executed the application by not closing the Statement and ResultSet objects. I did a query operation 50 times and observed the memory usage pattern.

Scenario 1
The database table contains 100 rows and 10 columns. ResultSet and Statement objects are closed. The database connection is made using a connection pool. The memory usage results of this scenario are shown in Figure 1.

Figure 1. When queried once, the heap memory usage increases by 166.308 KB. Click on thumbnail to view full-sized image.

Figure 1 is a heap usage chart provided by JProbe. It gives a runtime summary of the heap memory in use over time as the Java EE application runs. The green area indicates the heap usage. The vertical line indicates a heap usage checkpoint has been set at that time. After setting the checkpoint, the query occurs and the heap memory usage shoots up as objects are created. Once the operation completes, the objects no longer referenced will be garbage collected by the JVM, so the memory usage decreases. Ideally at this time, all new objects should be released and garbage collected, and the heap usage should return to the value before the checkpoint was set. In this case, some new objects continue to occupy memory space, reflecting an increase in heap usage by 166.308 KB.

  • Print
  • Feedback

Resources