Memory leaks in Java programs? Absolutely. Contrary to popular belief, memory management is still a consideration in Java programming. In this article, you'll learn what causes Java memory leaks and when these leaks should be of concern. You'll also get a quick hands-on lesson for tackling leaks in your own projects.
It is true that Java code does not require the programmer to be responsible for memory management cleanup, and that it automatically garbage collects unused objects. However, the key point to remember is that an object is only counted as being unused when it is no longer referenced.
Determining if an application has memory leaks
To see if a Java application running on a Windows NT platform is leaking memory, you might be tempted to simply observe the memory settings in Task Manager as the application is run. However, after observing a few Java applications at work, you will find that they use a lot of memory compared to native applications. Some Java projects that I have worked on can start out using 10 to 20 MB of system memory. Compare this number to the native Windows Explorer program shipped with the operating system, which uses something on the order of 5 MB.
Preventing memory leaks
You can prevent memory leaks by watching for some common problems. Collection classes, such as hashtables and vectors, are common places to find the cause of a memory leak. This is particularly true if the class has been declared static and exists for the life of the application.
Another common problem occurs when you register a class as an event listener without bothering to unregister when the class is no longer needed. Also, many times member variables of a class that point to other classes simply need to be set to null at the appropriate time.
Eliminating memory leaks
It is almost impossible to improve the performance of your code if your application is impacted by memory leaks. Memory leaks can be in either Java or native code. In native code, memory leaks are caused by the programmer forgetting to free a memory block. Java memory leaks are often caused by saving an object reference in a class level collection and forgetting to remove it at the proper time. There are also other kinds of problems with managing resources that impact performance, such as not closing JDBC Statements/ResultSets in a finally block (many JDBC drivers store a Statement reference in the Connection object). Fixing memory/resource leaks in the application not only has a great impact on performance but also system stability, as you will consume fewer resources.
There are some great tools in the marketplace that make it easy to find Java memory leaks. There are also tools for finding native memory leaks, but you shouldn’t need them unless your company is writing native code. It should suffice to monitor the memory used at the operating system level over a period of time while the client load test is running. In theory, if the application is repeating the same operations, total process memory should not creep up over time (it should level off). If the total memory of the Java process increases each time the client load test is run, then you probably have a memory leak to track down.
To determine if the memory leak is caused by a Java memory leak, you should monitor the Java memory used. The following code can be used for this purpose in the application:
System.out.println(“Java memory in use = “ + Runtime.getRuntime().totalMemory() – Runtime.getRuntime().freeMemory());
You would want to view this information after running the client test load. If the Java memory is increasing in proportion to the total process memory increase, then you are probably leaking Java memory. If the Java memory is stabilized but the total process memory is increasing, you are probably leaking native memory. You have to make a judgment call on whether this technique applies to your application. If the application is designed to consume additional memory after each client request, then this technique will not help you determine if you have a memory leak. You will have to use commercially available Java/native memory leak finding tools instead.
- Bea JRockit
- Quest Software's JProbe Suite
- Borland's Optimizeit Enterprise Suite
- Paul Moeller's Win32 Java Heap Inspector