Tuesday, July 27, 2010

Can a Java application have memory leak?

Yes, there could be memory leak in Java applications. Wait a minute, doesn't Java virtual machine have a garbage collector that will collect and free all unreferenced memory automatically?

Let's find out in general what memory leaks are, and how they occur in applications. If an application fails to return the not-in-use memory back to the heap, the "lost" memory is called memory leak.

Memory leaks occur when the application doesn't free the memory allocated, usually are the objects no longer in use, but the object references are lost. If an object is no longer accessible, there is no way to free its memory. Each time such a leak is re-created, additional memory is used and not freed. Eventually, the process that runs the application will run out of memory and crash.

It's true that for other programming languages, such as C/C++, there is not such a thing called garbage collector. The programmer is responsible for freeing the memory when the object is no longer in use.

In Java, all unreferenced objects are indeed automatically freed by the garbage collector. The garbage collector looks for objects that are no longer needed and to remove them when they can no longer be accessed or referenced. The garbage collector starts at the root nodes, classes that persist throughout the life of a Java application, and sweeps though all of the nodes that are referenced. As it traverses the nodes, it keeps track of which objects are actively being referenced. Any classes that are no longer being referenced are then eligible to be garbage collected. The memory resources used by these objects can be returned to the Java virtual machine (JVM) when the objects are deleted.

But in some situations, when the object is no longer in use, but some references to that object has not been removed. This kind of objects will not be collected by the garbage collector. That means there is a memory leak. Sometimes memory leaks in Java is also referred to as "dangling references".

What are the symptoms of a memory leak?

When the application has a memory leak, basically, you will notice:

  1. Memory usage consistently increases during the application life span. Sooner or later the application will crash because out of memory.
  2. Performance consistently decreases. This is because more and more un collectable objects are in the heap, which will trigger the garbage collector to work more frequently and work longer, on the other hand, the application will run slower.
Typical Leaks

Now that we know it is indeed possible to create memory leaks in Java, let's have a look at some typical leaks and what causes them.

Global collections

It is quite common in larger applications to have some kind of global data repository, a JNDI-tree for example, or a session table. In these cases care has to be taken to manage the size of the repository. There has to be some mechanism in place to remove data that is no longer needed from the repository.

Caches

A cache is a data structure used for fast lookup of results for already-executed operations. Therefore, if an operation is slow to execute, you can cache the result of the operation for common input data and use that cached data the next time the operation is invoked. Usually, the application keeps adding new data that was not in the cache, but not controlling the size of the cache. Depends on what data is kept in the cache, the cache will potentially increase to too big for the application to handle. When designing the cache, the program has to make sure the cache has an upper bound on the amount of memory it will use.

No comments:

Post a Comment