In Java, I've done things like the following without thinking much about it:
public class Main {
public void run() {
// ...
}
public static void main(String[] args) {
new Main().run();
}
}
However, recently I've become unsure as to whether doing that is safe. After all, there is no reference to the Main
object after it's created (well, there is the this
reference, but does that count?), so it looks like there's a danger that the garbage collector might delete the object while it's in the middle of executing something. So perhaps the main
method should look like this:
public static void main(String[] args) {
Main m = new Main();
m.run();
}
Now, I'm pretty sure that the first version works and I've never had any problems with it, but I'd like to know if it's safe to do in all cases (not only in a specific JVM, but preferably according to what the language specification says about such cases).
Java Garbage collector tracks the live object and objects which are no more need are marked for garbage collection. It relieves developers to think of memory allocation/deallocation issues. When an object created in Java program is no longer reachable or used it is eligible for garbage collection.
Unfortunately, this desire to immediately free up memory must go unrequited, as there is no way to force garbage collection (GC) in Java.
An object is eligible to be garbage collected if its reference variable is lost from the program during execution. Sometimes they are also called unreachable objects. What is reference of an object? The new operator dynamically allocates memory for an object and returns a reference to it.
Java garbage collection is an automatic process. The programmer does not need to explicitly mark objects to be deleted. The garbage collection implementation lives in the JVM. Each JVM can implement garbage collection however it pleases; the only requirement is that it meets the JVM specification.
If an object method is being executed, it means someone is in possession of that reference. So no, an object can't be GC'd while a method is being executed.
For the most part garbage collection is transparent. It's there to remove the unnecessary complication of manual memory management. So, it will appear not to be collected, but what actually happens is more subtle.
Trivially, a compiler may completely elide the construction of the object. (By compiler, I mean a lower level compiler than javac. The bytecodes will be a literal transliteration of the source.) More obscurely, garbage collection typically runs in separate threads and actually remove the unaccessed object as a method on it is being run.
How can this be observed? The usual suspect in a finaliser. It may run concurrently with a method running on the object. Typically you would get around this problem with synchronized
blocks in both the finaliser and the normal methods, which introduces the necessary happens-before relationship.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With