Performance problems associated with GC Heap

Document ID : KB000031995
Last Modified Date : 14/02/2018
Show Technical Document Details

 

Introduction:

 

Some of the performance problems you may see associated with the GC Heap.

 

Instructions: 

 

There are several different categories of memory-related problems that CA encounters during its field engagements.

 

The most common of these is the memory leak. Literally, a Java memory leak is the result of objects remaining referenced after an application has completely finished using them. This tends to happen when an object that has a long lifespan within your application holds references to other objects with short lifespans.

 

For example, a Swing GUI application might have a singleton WindowBroker object that keeps a list of open windows. As windows are opened and closed, they should be added and removed from the WindowBroker's list. Swing doesn't have a well-defined teardown strategy, so it can be easy for a developer to forget to unregister all the listeners on a particular piece of UI within the window that is closing. If one of these listeners is kept by an object like the WindowBroker, the resulting reference can inadvertently keep all the memory associated with that window from being garbage collected.

 

Memory leaks manifest as steady increases in the baseline of the JVM's GC Heap Bytes in Use, where the baseline is defined as the bytes in use after a full garbage collect. Full garbage collects look different on different vendors' JVMs. Sun JVMs show a "copy collect" pattern that, depending on how the garbage collector is tuned, can delay a full garbage collect for an hour or longer even with the application is under heavy load. The easiest way to know whether a full garbage collect has taken place is to turn on verbose garbage collection statistics (usually, this can be accomplished with the -Xverbose:gc flag). You can also record the GC Heap Bytes In Use and graph them over a long timespan -- the garbage collection pattern jumps out very clearly with such analysis.

 

Diagnosing memory leaks is a much stickier problem. Traditionally, developers have had to use a profiler to examine the references in the GC Heap. This can be a frustrating and time consuming affair, as anybody who ever attempted such analysis can attest.

 

After observing that memory leaks tended to take place most often in the standard Java data structures, CA developed a tool to watch these data structures for anomalous growth. Any unusual growth patterns are flagged along with the allocation stack trace of the potentially leaky data structure. A developer can then analyze the actual size of this data structure while the application is being exercised. This doesn't necessarily pull the needle out of the haystack, but it does pull the handful of hay out of the haystack that is most likely to contain the needle.

 

Besides memory leaks, many server-side applications suffer from trying to keep too much session state. In some cases, reducing the session timeout can significantly reduce the memory load on the application server. But many times, the developers of the application simply didn't plan for the complexity of the result sets their queries would return and the application must be re-architected to ask for results in smaller pieces.

 

Many applications burn CPU cycles on temporary objects. Object instantiation is one of the most expensive calls in Java. If a single transaction requires more than ten thousand temporary object instances (e.g. String or Hashtable), you get hit twice: once on the creation and again on the increased frequency of garbage collection required to reclaim this memory.

 

Finding the ideal GC Heap settings is a matter of deciding the right balance point between high-frequency, quick garbage collects and low-frequency, slow garbage collects. If your application has a service level agreement requiring that no transaction return in more than ten seconds, then you may not be able to delay your full garbage collects more than a few minutes -- longer delays mean more memory to collect and longer stalls of the JVM. Many environments have asychronous garbage collectors available to address just this problem, and they can be worth investigating if you have extremely strict service level agreements for your application.