Tuesday, November 17, 2009

Memory Leak in Java? Does 'static' cause it?

Does 'static' cause Memory Leak in Java?

What's memory leak? In simple terms, it's unused but referenced (somehow because the programmer probably unintentionally forgot to remove the references once the use of the object was over) part of the memory. Before we start discussing if 'static' can cause memory leak in Java, let me assure you that whatever you've read about Garbage Collectors in Java, is still valid and it certainly takes care of most (almost all) of the memory allocation/reclaimation of Java objects. But, that alone doesn't remove the possibility of the presence of memory leak in a Java program - just for example, you might not only be using only Java objects in your Java program. Putting it differently, what if you have used some native objects and forgot to reclaim the memory explicitly because that's anyway not going to be taken care by the GC (which takes care of heap memory management only)... right?

Now that we agree with the possibility of a Java program having potential memory leaks, let's see if using 'static' can also be one of the potential reasons for memory leaks in Java.

How to find if your Java program contains Memory Leaks?

Well... the programmer should have kept their eyes open while development itself. Once the app is ready, one may like to use Profilers (available from many vendors) to analyze the object graphs.

If your Java app is usually crashing with 'OutOfMemoryError' after executing for a while then it should ring an alarm for the possibility of memory leaks in your app. Though, this doesn't necessarily mean your app is having memory leaks, it might be possible that the allocated heap space is not enough for the proper functioning of your app.

Does 'static' cause memory leak in Java?

'static' can't straightway be blamed for causing memory leaks. But, if the programmer has not well thought the usage and has not taken care of the setting the references to 'null' explicitly after using the static objects then they can definitely cause memory leaks. Let's see how.

As you know 'static' members will by default live for the entire life of an app unless they are explicitly set to 'null'. So, always make it a point to nullify the references as soon as you reach at a point in your code where the use of the static member is over. For example: suppose you have created a 'Statement' object from a DB Connection and the connection is a pooled one. Now as you know calling close() method on a pooled connection will not actually close the connection instead it will return the Connection object to the pool to be re-used. So, in such a case unless you explicitly close the 'Statement' object, it would keep consuming precious memory space for no real use. Just think the scenario where you have declared the 'Statement' object as a static member, it'll be maintained in the memory for the entire life time of the app even when the control is out of the scope. It's just a sample scenario and many of you might never have used 'Statement' object in such an irresponsible manner. It's just an attempt to show how the 'static' can be misused to cause memory leaks in Java.

Not that if your Statement object is non-static you should reply on the out-of-scope nullification (i.e., as soon as control is out of scope the local objects would be marked for re-claimation) as in case you still have a significant amount of code (in terms of time/space) after using the Statement last and before reaching the end of the local scope, it would be a sheer wastage of memory if you don't explicitly nullify the 'Statement' after its use is over. Such a scenario should also be thought of as memory leaks only and one should always make sure the nullification of resources is as close to their last usage as possible.

Therefore, in summary we can say that one should/must :-

  • always think if you really need to make this variable/member a 'static' one?
  • always try to confine the scope of an object to restrict its usage only to the section it's actually needed
  • always make a conscious effort to explicitly nullify objects once you finish using them (especially the large objects)

Liked the article? Subscribe to this blog for regular updates. Wanna follow it to tell the world that you enjoy GeekExplains? Please find the 'Followers' widget in the rightmost sidebar.



Anonymous said...

Thanks For the Explanation.

Thanga said...

How the Singleton object will affect the performance of the application?

Geek said...

Performance has more to do with the wise handling of the object(s). If Singleton being used effectively, it'll only boost the performance. Suppose, thousands of threads are coming in and they all are using the same Connection object, it's better to make it Singleton instead of forcing all the threads to have their own copies. Hope this helps. Keep posting!

Anonymous said...

Nice Explanation.

Anonymous said...

Not agree with Anonymous...
In case of multiple threads using same Connection Object it will slow down the performance.. coz .. evry thread hold lock on the connection ..

it would be better to use Connection Pooling... and not the singleton.

Geek said...

I think you should have noticed the usage of 'wise handling' and 'effectively'.

It depends upon the scenario whether one should go with Connection Pooling or Singleton. Not that one fits the bill every time.

What if the chances of having more than one thread at one point of time is very less, but we are in a multi-threaded model where new threads are being spawned and not the same thread being used - quite possible, right? Don't you think that maintaining the Pool will be costlier in such cases? Singleton will probably make more sense here. My intent in the above explanation was to convey that Singleton can also be used effectively to boost performance in certain cases - shared Connection object being just one example.

However, I do agree that Connection Pooling is a very effective mechanism to boost performance. But, so is the usage of Singleton. It all depends on the particular problem scenario. HTH.

Anonymous said...

I do not agree by your explanation, I declare static variable, knowing that it will be alive for the entire scope of application. Hence GC guarantee that by not reclaiming the object (Uses as a root as well for object graph traversal). Having any other usage of static variable is breaking the Oops concepts and there is a design flaw.
Whereas a well designed application can have memory leak problem. So blaming it on "Static" is not right


Geek said...

Hi Gaurav,

The particular section of the article starts with this line 'static can't straightway be blamed for causing memory leaks'. Why do you think that I'm blaming static for that? In fact, it's the other way... All I'm trying to say that 'static' can cause a memory leak only when not used effectively. Hope this helps!

Unknown said...

thanks for your explaination