As a Java-lover, I can say this is the "Million Dollar Question"...
The answer is that it depends on what kind of memory leak you are talking about.
Classic C / C++ memory leaks occur when an application neglects to
free
or dispose
an object when they are done with it, and it leaks. Cyclic references are a sub-case of this where the application has difficulty knowing when to free
/ dispose
, and neglects to do it as a result. Related problems are where the application uses an object after it has been freed, or attempts to free it twice. (You could call the latter problems memory leaks, or just bugs. Either way ... )
Java and other (fully1) managed languages mostly don't suffer from these problems because the GC takes care of freeing objects that are no longer reachable. (Certainly, dangling pointer and double-free problems don't exist, and cycles are not problematic as the are for C / C++ "smart pointers".)
But in some cases GC in Java will miss objects that (from the perspective of the programmer) should be garbage collected. This happens when the GC cannot figure out that an object cannot be reached:
- The logic / state of the program might be such that the execution paths that would use some variable cannot occur. The developer can see this as obvious, but the GC cannot be sure, and errs on the side of caution (as it is required to).
- The programmer could be wrong about it, and the GC is avoiding what might otherwise result in a dangling reference.
Well, considering that java uses a garbage collector to collect unused objects, you can't have a dangling pointer. However, you could keep an object in scope for longer than it needs to be, which could be considered a memory leak....
Now let's, be more practical and perform a real test to see how the Java Garbage Collection works.
As we know (hope you do), the Finalize() is invoked right before an object is garbage collected, so, to demonstrate how this works we might need to create objects and wait for them to be 'garbage collected'.
On your favorite IDE, copy / paste the next code snippet:
package com.rolandoFebreroo.GarbageCollection; public class GarbageCollection { public static void main(String args[]) { for (int i = 0; i < 10; i ++) { new MyObject(); } } } class MyObject { MyObject() { super(); System.out.println("Object reference is located on the heap at: " + this); } protected void finalize() { System.out.println("!!!You have been Finalized, baby...!!! " + this ); } }
As we can see, there is a simple for loop used to create 10 MyObject objects. The output is:
Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@15db9742 Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@6d06d69c Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@7852e922 Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@4e25154f Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@70dea4e Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@5c647e05 Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@33909752 Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@55f96302 Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@3d4eac69 Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@42a57993
Still we are not able to see how the Garbage Collector works, and if we run the same code again, we are going to get the exact same memory address for the newly created objects.
How come we didn't see the the finalize() method execute? Finalize() is not called when an object is no longer in scope, finalize is called just prior to garbage collection. Because of this, your program should utilize other methods of executing statements that need to be run before the object is destroyed. Things like closing file handles, freeing up resources, etc., should not depend on finalize() for normal program execution.
We have no way of knowing when the garbage collector is going to run. In this case, the garbage collector ran sometime after the completion of my main method, so the string literal "!!!!You have been Finalized, baby...!!!" could not be displayed to the console.
In order to demonstrate the finalize() method, I will make an infinite loop that creates an object on every iteration. Hopefully, we will see some "!!!You have been Finalized, baby...!!! " roll across the console.
For this purpose, just modify the for loop and increment the value from 'i<10' to 'i<100000'
for (int i = 0; i < 100000; i ++)
Now, Let's run the code again, but this time you should get an output similar to this:!!!You have been Finalized, baby...!!! com.rolandoFebreroo.GarbageCollection.MyObject@2314cd97 !!!You have been Finalized, baby...!!! com.rolandoFebreroo.GarbageCollection.MyObject@5af56240 !!!You have been Finalized, baby...!!! com.rolandoFebreroo.GarbageCollection.MyObject@2212e291 !!!You have been Finalized, baby...!!! com.rolandoFebreroo.GarbageCollection.MyObject@5d75f90e !!!You have been Finalized, baby...!!! com.rolandoFebreroo.GarbageCollection.MyObject@31b91435 Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@6ae9b2f0 Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@3f1870bc Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@3993c2be Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@55b0c0a6 Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@726986d2 Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@e0895b3 Object reference is located on the heap at: com.rolandoFebreroo.GarbageCollection.MyObject@29a920fe
This was just a simple exercise to understand how Java Garbage Collection works. Just remember that since Finalize() is only called right before an object is garbage collected, and this might or might not happen during the execution of your program, you shouldn't place any code that NEEDS to be executed in the Finalize().
Programming thought of the day:
- Wikipedia: I know everything!
- Google: I have everything!
- Facebook: I know everybody!
- Internet: Without me you are nothing!
- Electricity: Keep talking bitches!
No comments:
Post a Comment