Plug memory leaks in enterprise Java applications

Strategies for detecting and fixing enterprise memory leaks

Page 2 of 2

HttpSession vs. HttpRequest

HTTP is a request-response-based stateless protocol. If a client wants to send information to the server, it can be stored in an HttpRequest object. But that HttpRequest object will be available only for a single transaction. The HTTP server has no way to determine whether a series of requests came from the same client or from different clients. The HttpSession object is generally used to store data required from the time a user logs into the system until he logs out. It brings statefulness into a transaction. The session can be used for storing information such as a user's security permissions. But often, programmers mistakenly store complex long-living data, such as a shopping cart, into the session, instead of using the business tier.

I experimented with the sample application to find the difference in memory usage between the HttpSession and HttpRequest objects since data stored in HttpSession will stay in memory until the user logs out of the application. I added the database table's query results to an ArrayList, which I then placed into both the HttpSession and HttpRequest objects. Memory usage was observed for 50 query-and-save operations.

Scenario 1

The database table contains 100 rows. The output ArrayList is stored in the HttpRequest object to be passed back to the JSP page.

After performing one query-and-save operation, the increase in memory usage is 166.308 KB.

Figure 11. Results for one query-and-save operation. Click on thumbnail to view full-sized image.

After completing 10 query-and-save operations, the increase in memory usage is 175.512 KB.

Figure 12. Ten operations. Click on thumbnail to view full-sized image.

After performing 50 query-and-save operations, the increase in memory usage is 194.128 KB.

Figure 13. Fifty query-and-save operations. Click on thumbnail to view full-sized image.

Scenario 2

The database table contains 100 rows. The output ArrayList is stored in the HttpSession object to be passed back to the JSP page.

After one query-and-save operation, the increase in memory usage is 176.708 KB.

Figure 14. One query-and-save operation. Click on thumbnail to view full-sized image.

After 10 query-and-save operations, the increase in memory usage is 178.46 KB.

Figure 15. Ten operations. Click on thumbnail to view full-sized image.

After 50 query-and-save operations, the increase in memory usage is 216.552 KB.

Figure 16. Fifty operations. Click on thumbnail to view full-sized image.

When the data is stored in HttpSession, instead of HttpRequest, 50 save-and-query operations increase memory usage by 22.424 KB. This happens on a per client basis. Hence for multiple clients, the multiplicative factor comes in as well. Over a period of time, this will definitely lead to a significant memory leak in the application.

The data stored in HttpSession stays in memory as long as the user is logged in. Putting too much data into HttpSession leads to the Overstuffed Session anti-pattern. Since HttpSession is implemented as a collection, this overstuffed session can be considered a variant of the Leak Collection anti-pattern.

Recommendation

  1. Use of HttpSessions should be minimized and used only for state that cannot realistically be kept on the request object
  2. Remove objects from HttpSession if they are no longer used
  3. Long-living data should be migrated to the business tier

Conclusion

I have highlighted some of the important programming scenarios where the JVM's garbage collection mechanism becomes ineffective. These situations necessitate appropriate precautions during design of the application itself. While closing ResultSets and Statements can be done after application development with comparatively low costs, other aspects that I have explained get deeply embedded in the design and could prove costly to correct.

The garbage collector is a low-priority thread. Hence in a heavily loaded Java EE application, garbage collection itself may happen infrequently. Even those objects that could have been potentially garbage collected may actually stay in memory for a long time. So explicitly cleaning the heap may be a mandatory programming requirement in some applications; doing so must be considered on a case-by-case basis.

Ambily Pankajakshan works as a scientist in the Centre for Artificial Intelligence and Robotics. She has more than five years of experience in the design and development of multitiered Java EE applications. Her areas of interests are performance-tuning Java EE applications and application servers. She holds a B.Tech Degree in computer science and engineering from M.G. University, Kerala India. Currently, she lives in Bangalore with her husband Nishore and son Ananthu.

Learn more about this topic

| 1 2 Page 2