user918076
user918076

Reputation:

Java Memory Leaks

I'm creating a service that will run constantly, each day at a specified time it will run the main body of the program.

Essentially:

while(true){
run();
Thread.sleep(day);
}

After a while, I'm getting OutOfMemoryHeapExceptions. After reading about this a little I'm thinking its because any objects created inside the run() method will never be garbage collected.

Therefore I have done something like:

public void run(){
Object a = new Object();
a.doSomething();

a= null; //Wasn't here before
}

My question is, will this solve my problem? I'm under the impression that once an object is null, the object it previously referenced will be garbage collected? Also is this a good idea? Or should I look at doing something else?

Thanks

Upvotes: 1

Views: 330

Answers (8)

NPE
NPE

Reputation: 500157

Adding a = null will almost certainly be insufficient to fix the problem (since a is about to go out of scope anyway).

My advice would be to use a memory profiler to pinpoint what's leaking and where.

I personally use YourKit. It's very good, but costs money (you can get a free evaluation).

Another recently-released tool is Plumbr. I am yet to try it, but the blurb says:

Try out our Java agent for timely discovery of memory leaks. We'll tell you what is leaking, where the leak originates from and where the leaked objects currently reside - well before the OutOfMemoryError!

Upvotes: 2

Brad
Brad

Reputation: 15879

In the short term a pragmatic approach to keeping your application stable is to exit the JVM after each execution. Use a batch scheduler (e.g. cron on *nix, at on Windows) to execute your application just once every day. Any memory leaks will be cleaned up when the JVM exists for sure. However you may have to be careful you're not leaving database connections open, etc.

This will give you time to troubleshoot and fix the underlying memory leak issues while keeping your production code running and not requiring support staff to restart servers, etc.

I'm assuming you're not running out of memory on a single execution

Upvotes: 0

Thomas
Thomas

Reputation: 88707

You should get a memory dump and analyze that using tools like JConsole JVisualVM.

The scope of the run() method is left before the Thread.sleep(day); and thus any variables inside that method are destroyed. After that a won't exist any more and thus the object referenced by that variable might be eligible for garbage collection provided there's no other reference to it.

Analyzing a memory dump should allow you to find any references to those object if they still exist.

It might as well not be those objects but others that are kept alive and which eat up the memory. That depends on what you're actually doing and might be hard to analyze here. Thus look out for huge object graphs in terms of memory usage.

For instance, we had a problem with database connections that were created frequently (XA recovery mechanism) and we thought they'd be destroyed once the method scope is left. However, the server put those connections into a static list and never cleared it and thus we ended up with no memory really soon. What helped us identify that case was analyzing a memory dump. :)

Upvotes: 0

alishaik786
alishaik786

Reputation: 3726

Local variables should be collected by GC. So, you don't need to put obj=null;. Because Object is also stored in Heap area.

Upvotes: 0

mprabhat
mprabhat

Reputation: 20323

Setting references to null depends if your object is still in scope in a long time consuming process, though theoretically it will mark the reference as null you cannot guarantee when it will be garbage collected.

You need to check if your objects are being held in long scope somewhere in your code.

Found a nice explanation of setting references to null : Does setting Java objects to null do anything anymore?

In order to corner out your issue you need to profile your application.

Searching SO gave so many pointers on Garbage Collection that I have decided to just place the search string here:

https://stackoverflow.com/search?q=Java+Garbage+collection+and+setting+references+to+null

http://java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html

Upvotes: 0

SJuan76
SJuan76

Reputation: 24780

No. You don't need to set the variable to null. The VM knows that you exit that scope and that the variable a no longer exists, so it automatically decrements the reference count and your object is elegible for garbage collection if it had no other references.

The error is somewhere else.

Upvotes: 0

pcalcao
pcalcao

Reputation: 15965

That might indeed help, in some circumstances the GC algorithm needs a little help to perform, but it doesn't guarantee to solve your problems, merely delay them.

My advice: Simulate the same behavior with a lower time period, so you can force the error to happen. Run it with a profiler and see where all that memory is going, and work from there.

Upvotes: 1

mcfinnigan
mcfinnigan

Reputation: 11638

Your impression is incorrect. Objects created inside the run() method will be garbage collected provided they 1) go out of scope, and 2)have released any native or remote system resources they are using.

What functionality are you actually performing inside your run() method call? Are you reading files, making database calls, writing to sockets? Without knowing the details its very difficult to provide a better suggestion.

Upvotes: 0

Related Questions