Chapter 10. The Memory Leak Detector

As described in the chapter on memory management, the Java runtime provides a simplified memory model for the programmer. The developer does not need to reserve memory from the operating system for storing data, nor does he need to worry about returning the memory once the data is no longer in use.

Working with a garbage collected language could easily lead to the hasty conclusion that resource management is a thing of the past, and that memory leaks are impossible. Nothing could be further from the truth. In fact, memory leaks are so common in Java production systems that many IT departments have surrendered. Recurring scheduled restarts of Java production systems are now all too common.

In this chapter, you will learn:

  • What we mean by a Java memory leak
  • How to detect a memory leak
  • How to find the cause of a memory leak using the JRockit Memory Leak Detector

A Java memory leak

Whenever allocated memory is no longer in use in a program, it should be returned to the system. In a garbage collected language such as Java, quite contrary to static languages such as C, the developer is free from the burden of doing this explicitly. However, regardless of paradigm, whenever allocated memory that is no longer in use is not returned to the system, we get the dreaded memory leak. Eventually, enough memory leaks in a program will cause it to run out of memory and break.

Memory leaks in static languages

In static languages, memory management may be even more complex than just recognizing the need to explicitly free allocated memory. We must also know when it is possible to deallocate memory without breaking other parts of the application. In the absence of automatic memory management, this can sometimes be difficult. For example, let's say there is a service from which address records can be retrieved. An address is stored as a data structure in memory for easy access. If modules A, B, and C use this address service, they may all concurrently reference the same address structure for a record.

If one of the modules decides to free the memory of the record once it is done, all the other modules will fail and the program will crash. Consequently, we need a firm allocation and deallocation discipline, possibly combined with some mechanism to let the service know once every module is done with the address record. Until this is the case, it cannot be explicitly freed. As has been previously discussed, one approach is to manually implement some sort of reference counting in the record itself to ensure that it can be reclaimed once all modules are finished with it. This may in turn require synchronization and will add complexity to the program. To put it simply, sometimes, in order to achieve proper memory hygiene in static languages, the programmer may have to implement code that behaves almost like a garbage collector.

Memory leaks in garbage collected languages

In Java, or any garbage collected language, this complexity goes away. The programmer is free to create objects and the garbage collector is responsible for reclaiming them. In our hypothetical program, once the address record is no longer in use, the garbage collector can reclaim its memory. However, even with automatic memory management, there can still be memory leaks. This is the case if references to objects that are no longer used in the program are still kept alive.

The authors once heard of a memory leak in Java being referred to as an unintentional object retention. This is a pretty good name. The program is keeping a reference to an object that should not be referenced anymore. There are many different situations where this can occur.

Perhaps the leaked object has been put in a cache, but never removed from the cache when the object is no longer in use. If you, as a developer, do not have full control over an object life cycle, you should probably use a weak reference-based approach. As has previously been discussed, the java.util.WeakHashMap class is ideal for caches.

Note

Be aware that weak references is not a one-size-fits-all answer to getting rid of memory leaks in caches. Sometimes, developers misuse weak collections, for instance, by putting values in a WeakHashMap that indirectly reference their keys.

In application containers, such as a J2EE server, where multiple classloaders are used, special care must be taken so that classes are not dependency injected into some framework and then forgotten about. The symptom would typically show up as every re-deployment of the application leaking memory.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.133.123.34