views:

118

answers:

4

In almost all larger Java projects I've been involved with I've noticed that the quality of service of the application degrades with the uptime of the container. This is most probably due to memory leaks in the code.

The correct way to solve this problem is obviously to trace back to the root cause of the problem and fix the leaks in the code. The quick and dirty way of solving the problem is simply restarting Tomcat (or whichever servlet container you're using).

These are my three questions:

  • Assume that you choose to solve the problem by tracing the root cause of the problem (the memory leaks), how would you collect data to zoom in on the problem?

  • Assume that you choose the quick and dirty way of speeding things up by simply restarting the container, how would you collect data to choose the optimal restart cycle?

  • Have you been able to deploy and run projects over an extended period of time without ever restarting the servlet container to regain snappiness? Or is an occasional servlet restart something that one has to simply accept?

+1  A: 

Ideally, you should not need to restart your program or servlet.

My experience is that most causes of memory problems usually result from a problem in the allocation or pooling of a small set of classes.

A tool like VisualVM is great for that, since you can figure out where the brunt of your object allocation is located.

It's probably a little trickier with tomcat since you will also be monitoring the framework, but with sufficient care and patience you can often identify hotspots in your logic.

Uri
+8  A: 

Assume that you choose to solve the problem by tracing the root cause of the problem (the memory leaks), how would you collect data to zoom in on the problem?

Take a heap dump using jmap and load the dump using Eclipse Memory Analyzer. From there you can analyze which objects are eating up the most memory, which "roots" are preventing other objects from being collected, etc.

There are other heap analysis programs, such as jhat, but I've found EMA to be the fastest and best (free) solution.

Assume that you choose the quick and dirty way of speeding things up by simply restarting the container, how would you collect data to choose the optimal restart cycle?

Use JMX to monitor heap size and other heap and GC statistics.

Have you been able to deploy and run projects over an extended period of time without ever restarting the servlet container to regain snappiness?

Yes. By avoiding/fixing memory leaks.

matt b
+1 for the simple, no-nonsense answer. Restarting the container is a simple work-around, but not a long-term solution. Automating the container restart is an automated work-around, which has some of the benefits of a solution, but has a lot of drawbacks too.
Edwin Buck
+1  A: 

There are some great profiling tools out there. Learn to use one regularly and understand the memory allocation output.

Basically you follow this process for each important function of your app:

  • Run through the process once
  • GC twice
  • Mark your current allocation counts for all objects
  • run through your process again
  • GC twice
  • Mark again
  • Diff the two marks

If they are not extremely close, you probably have a leak.

If any object count grows by a given amount every iteration of this process then you absolutely have a leak.

Bill K
+3  A: 

even if your code has no real issues, there can be some memory leaks if you are using apache. check out http://www.tomcatexpert.com/blog/2010/04/06/tomcats-new-memory-leak-prevention-and-detection for tips and suggestions

Pablo Grisafi
Very interesting. Nice!
tucuxi