0

Is Making the instances as Orphan in finally block requests GC to perform garbage collection on high priority?

SQLConnect ds =null;
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
...  
variables  

try {
    //Business Logic       
} catch(Exception e) {
    //Logging goes here
} finally {
    //Make instances Orphan
    ds = null;
    con = null;
    pstmt = null;
    rs = null;
}
HpTerm
  • 8,151
  • 12
  • 51
  • 67
Nagappa L M
  • 1,452
  • 4
  • 20
  • 33
  • 2
    No. Why should it? It just makes the instances candidates for being collected if nobody else references them. (What do you mean by "on high priority"?) – TheBlastOne Jun 28 '13 at 06:11
  • 3
    A memory leak by definition is an undesirable increase which cannot be cleaned up by the GC. – Peter Lawrey Jun 28 '13 at 06:16

5 Answers5

10

No. You're doing something pointless (setting local variables to null when they're not going to be used any more anyway) but you're not doing something you should be: closing the statement/connection.

You should just use either call close in finally blocks, or use try-with-resources statement if you're using Java 7, which makes life simpler:

try (Connection conn = ...)
{
    try (PreparedStatement statement = ...)
    {
        try (ResultSet rs = ...)
        {
            ...
        }
    }
}

Setting variables to null for the sake of garbage collection is almost never worthwhile - but calling close on instances which hold non-memory resources (file handles, network handles, database handles etc) is always a good idea. You really don't want to wait until a finalizer happens to clean up for you before releasing those resources.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Dammit. I was just typing that up :-) – Thihara Jun 28 '13 at 06:15
  • 1
    @Thihara: This was my second attempt - I originally wrote code thinking the question was about C#, and had to delete it while I edited! – Jon Skeet Jun 28 '13 at 06:17
  • Please note, that this only works for classes which implement the ´AutoCloseable´ interface. This is the case for all used classes in the given example. – BetaRide Jun 28 '13 at 06:21
  • 1
    It makes sense to set the references to `null` if the rest of the method will have a long life span. Not that I'm suggesting this is a good thing, I'm just pointing out the cases when it is worthwhile to `null` out references. – SimonC Jun 28 '13 at 06:22
  • 1
    @JonSkeet I guess that makes you real fast? :-O Or me real slow... :-/ – Thihara Jun 28 '13 at 06:50
  • @SimonC: I thought I'd replied to this earlier, but apparently it didn't get through. In those cases, it's almost always a better idea to extract a smaller method. In the .NET CLR, variables which aren't read later in the method aren't treated as GC roots anyway, but unfortunately I don't think most Java VMs work that way :( – Jon Skeet Jun 28 '13 at 10:28
5

Is Making the instances as Orphan in finally block requests GC to perform garbage collection on high priority?

No. Assigning null does not change the "priority" at which objects are garbage collected. Indeed, assuming that the scope for those variables is about to end, assigning null to them is pointless.

(Assigning null to some variable or field in Java does not decrement reference counts, etc, and does not trigger the corresponding object to be reclaimed. In fact, the completely GC is oblivious to the assignment event. The most the assignment can do is to make the object unreachable sooner. But in this example where the variable is about to go out of scope, this is going to happen almost immediately anyway. Hence the null assignment doesn't achieve anything.)

The garbage collection is going to run when the JVM thinks it is the right time, irrespective of what you do. Apart from calling System.gc() ... which is a really bad idea for other reasons!


Under normal circumstances, you shouldn't worry about when the GC runs. However, in this case you are dealing with external resources; i.e. database connections, resultsets and the like. These need to be "managed" properly, or you are liable to run into problems with resource leaks.

If / when the objects do get GC'ed, they will probably be closed by their respective finalize methods. However, the finialization may well happen too late to avoid the bad consequences of the resource leaks.

So the correct way to manage these is NOT to null them in the (vain) hope that they will be GC'ed sooner. The correct way to deal with them is to explicitly call their respective close() methods ... in the finally block; e.g.

finally {
    conn.close();  // This should also close any child Statement and 
                   // ResultSet instances
}

And a better way to do this is to use Java 7 "try with resource" syntax as described by Jon Skeet's answer.

Community
  • 1
  • 1
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
1

Please don't mess with the garbage collector. This leads very often to code that is difficult to understand but does not increase any performance.

As long as there is at least one reference to an object the garbage collector will not collect the object, no matter what you do.

If there is no more reference to an object the garbage collector will collect the object. The garbage collector runs when the memory is getting low.

Please be aware that some objects (like Connection in your case) are also aquire external resources. This resources must be released manually each time. Therefore it is much more important to close the Connection in the finally block than setting it to null.

Uwe Plonus
  • 9,803
  • 4
  • 41
  • 48
1

Memory leaks in java have nothing to do with how often or when does the garbage collector do it's job!

Memory is leaked when it is never going to be used again and can not be freed.

Your problem, possibly, is with resources management. Handling DB connections is a good example of managing resoruces, and you should consider using some kind of Connection Pool

Side note: to get information on how memory leaks look in Java, visit this question: Creating a memory leak with Java

Community
  • 1
  • 1
Dariusz
  • 21,561
  • 9
  • 74
  • 114
0

No. Absolutely no. A thousand times no.

Java is a memory managed language. You do yourself no favors by trying to force the JVM to manage memory in a way that is different from the way in which it will ordinarily manage memory. Such schemes are necessarily JVM implementation dependent, not portable, and are likely to cause you more problems than would be fixed.

The best way to avoid memory leaks in Java:

  • Confine object references to the narrowest possible scope. Often, you'll limit the scope of an object's reference to a single method or block. As soon as the reference falls out of scope, it will become eligible for garbage collection.

  • Null out object references ONLY for reference types that represent your own implementation of managed memory. In Effective Java, 2nd Ed., Joshua Bloch gives an example of a simple cache of references. When the cache shrinks, he recommends nulling out the no longer used references (that would otherwise be held and keep the respective objects from becoming eligible for collection). He calls this "memory that you have chosen to manage yourself."

  • Avoid "leaking" references of otherwise short-lived objects into contexts where these references could be held by a long-lived variable. An inner class represents a situation in which this can happen.

  • Free up resources for long-lived objects that are resource intensive. Examples would be database connections and certain GUI controls.

As long as you keep reference types limited to the narrowest possible scope, most of the time you never need to worry about garbage collection.

scottb
  • 9,908
  • 3
  • 40
  • 56