Garbage collection of referenced objects in Java - java

I have the following code:
class Test {
public static void main(String[] args) {
String a,b,c;
a = new String(args[0]);
b = a;
a = null;
b = null;
}
}
Can someone tell me when a will be eligible for garbage collection. I think it's after b is made null because don't a and b reference the same object ?

Pitching my answer too. As the other answers say, the String/ object is available for Garbage Collection once it is no longer accessible (you no longer have a handle to it).
So if you had a one-direction linked list... [1] -> [2] -> [3] and you had a handle to [1] (which has a handle to [2] and onwards). If you set your handle to [1] to null, you would put the entire list available to the Garbage collector. As this answer says, you are able to call System.gc() to request the Garbage Collector run, but it is not guaranteed that it will.
I believe the main focus to this answer is that objects are available to the garbage collector when they are inaccessible and that does not necessarily mean that there are no references to it. In my above example, even though [1] had a handle to [2], [2] was available for the garbage collector because there was no handle to [1].

The object you've created, new String(args[0]);, will be eligible for collection once there are no longer any references to it. So let's step through the code:
a = new String(args[0]);
a points to your String, it is not eligible for collection.
b = a;
a and b point to your String, not eligible.
a = null;
b points to your String, not eligible.
b = null;
No references to your String, Garbage Colelctor is happy!

What do you mean by a? a is a reference, and only objects are garbage collected.
The string referenced by a, and then b, is eligible for garbage collection when nothing references it anymore. In this case, this is after both references to the string (a and b) have been changed to reference something else; in this case, null.

You must reason in terms of allocated objects: the String you allocated is not referenced by anyone as soon as you nullify both a and b. From thereon the garbage collector is entitled to do its job.

class Test {
public static void main(String[] args) {
String a,b,c; // you dont have objects yet
a = new String(args[0]); // here u make a new object
b = a; // b references to the same object as a
a = null; // a points to null, reference is removed.
b = null; // b point to null, reference is removed
}
}
in your program the object that was created and assigned to a and b will be garbage collected after references are removed.
Garbage collector will clean up the object that has no roots and not being referenced by anything.

Related

How to delete object inside method? [duplicate]

I want to delete an object I created, (a oval which follows you), but how would I do this?
delete follower1;
didn't work.
EDIT:
Okay, I'll give some more context. I'm making a small game with a oval you can control, and a oval which follows you. Now I've got files named: DrawPanel.class, this class draws everything on the screen, and handles collisions, sounds, etc. I got an enemy.class, which is the oval following the player. I got an entity.class, which is the player you can control. And if the player intersects with the follower, I want my player object to get deleted. The way I'm doing it:
public void checkCollisions(){
if(player.getBounds().intersects(follower1.getBounds())){
Follower1Alive = false;
player.health = player.health - 10;
}
}
You should remove the references to it by assigning null or leaving the block where it was declared. After that, it will be automatically deleted by the garbage collector (not immediately, but eventually).
Example 1:
Object a = new Object();
a = null; // after this, if there is no reference to the object,
// it will be deleted by the garbage collector
Example 2:
if (something) {
Object o = new Object();
} // as you leave the block, the reference is deleted.
// Later on, the garbage collector will delete the object itself.
Not something that you are currently looking for, but FYI: you can invoke the garbage collector with the call System.gc()
Your C++ is showing.
There is no delete in java, and all objects are created on the heap. The JVM has a garbage collector that relies on reference counts.
Once there are no more references to an object, it becomes available for collection by the garbage collector.
myObject = null may not do it; for example:
Foo myObject = new Foo(); // 1 reference
Foo myOtherObject = myObject; // 2 references
myObject = null; // 1 reference
All this does is set the reference myObject to null, it does not affect the object myObject once pointed to except to simply decrement the reference count by 1. Since myOtherObject still refers to that object, it is not yet available to be collected.
If you want help an object go away, set its reference to null.
String x = "sadfasdfasd";
// do stuff
x = null;
Setting reference to null will make it more likely that the object will be garbage collected, as long as there are no other references to the object.
You don't need to delete objects in java. When there is no reference to an object, it will be collected by the garbage collector automatically.
You can remove the reference using null.
Let's say You have class A:
A a = new A();
a=null;
last statement will remove the reference of the object a and that object will be "garbage collected" by JVM.
It is one of the easiest ways to do this.
Java has a Garbage Collector, it will delete the object for you if no reference is held to it anymore.
//Just use a List
//create the list
public final List<Object> myObjects;
//instantiate the list
myObjects = new ArrayList<Object>();
//add objects to the list
Object object = myObject;
myObjects.add(object);
//remove the object calling this method if you have more than 1 objects still works with 1
//object too.
private void removeObject(){
int len = myObjects.size();
for(int i = 0;i<len; i++){
Objects object = myObjects.get(i);
myObjects.remove(object);
}
}

How does Java handle returning references when using finally blocks in Java with regards to GC?

In the scenario below how what happens with regards to GC?
I'm pretty sure the reference to "a" will not actually get returned, hence no need to worry about leaving this reference in scope.
So pretty much the return of "a" never actually takes place and therefore goes out of scope and only "b" is ever returned?
Object testFinally(){
try {
Object a = new Object();
return a;
} finally {
Object b = new Object();
return b;
}
}
void callToTestFinally(){
Object v = testFinally();
}
Same procedure as always. If an instance is no longer reachable by a strong refererence, it will be eligible for garbage collection. Nothing different for your a and finally, it goes out of scope and can be collected.

How many objects will be eligible for garbage collection?

So I've recently been to job interview and was asked the following question. (Actually it was just a test writing, so I couldn't ask any questions)
At the end of the main method, how many objects will be eligible for garbage collection?
public class Main {
public static void main(String[] args) {
Object obj;
for (int i = 0; i < 5; i++) {
obj = new Object();
}
obj = null;
}
}
(A) 0
(B) 1
(C) 5
I know it's 0 because at least one object (obj) will be garbage collected, but I also know that obj is not really the object, it's just a reference to it. So my answer was 5.
Is that correct? If not, then why?
Your answer 5 is correct.
Here total 5 number of objects are created through for loop and all of these will be eligible for garbage collection at the end of the method.
Probably 0,
The compiler might workout some optimisation and eliminate the entire loop and avoid creating the five objects created in the loop in the first place.
So if no compiler optimisation is going on, 5 objects are created inside the loop and their references is being overwritten in the variable obj, at the end variable will reference the last object which is being assigned to null.

Delete Reference of Inner Class [duplicate]

I want to delete an object I created, (a oval which follows you), but how would I do this?
delete follower1;
didn't work.
EDIT:
Okay, I'll give some more context. I'm making a small game with a oval you can control, and a oval which follows you. Now I've got files named: DrawPanel.class, this class draws everything on the screen, and handles collisions, sounds, etc. I got an enemy.class, which is the oval following the player. I got an entity.class, which is the player you can control. And if the player intersects with the follower, I want my player object to get deleted. The way I'm doing it:
public void checkCollisions(){
if(player.getBounds().intersects(follower1.getBounds())){
Follower1Alive = false;
player.health = player.health - 10;
}
}
You should remove the references to it by assigning null or leaving the block where it was declared. After that, it will be automatically deleted by the garbage collector (not immediately, but eventually).
Example 1:
Object a = new Object();
a = null; // after this, if there is no reference to the object,
// it will be deleted by the garbage collector
Example 2:
if (something) {
Object o = new Object();
} // as you leave the block, the reference is deleted.
// Later on, the garbage collector will delete the object itself.
Not something that you are currently looking for, but FYI: you can invoke the garbage collector with the call System.gc()
Your C++ is showing.
There is no delete in java, and all objects are created on the heap. The JVM has a garbage collector that relies on reference counts.
Once there are no more references to an object, it becomes available for collection by the garbage collector.
myObject = null may not do it; for example:
Foo myObject = new Foo(); // 1 reference
Foo myOtherObject = myObject; // 2 references
myObject = null; // 1 reference
All this does is set the reference myObject to null, it does not affect the object myObject once pointed to except to simply decrement the reference count by 1. Since myOtherObject still refers to that object, it is not yet available to be collected.
If you want help an object go away, set its reference to null.
String x = "sadfasdfasd";
// do stuff
x = null;
Setting reference to null will make it more likely that the object will be garbage collected, as long as there are no other references to the object.
You don't need to delete objects in java. When there is no reference to an object, it will be collected by the garbage collector automatically.
You can remove the reference using null.
Let's say You have class A:
A a = new A();
a=null;
last statement will remove the reference of the object a and that object will be "garbage collected" by JVM.
It is one of the easiest ways to do this.
Java has a Garbage Collector, it will delete the object for you if no reference is held to it anymore.
//Just use a List
//create the list
public final List<Object> myObjects;
//instantiate the list
myObjects = new ArrayList<Object>();
//add objects to the list
Object object = myObject;
myObjects.add(object);
//remove the object calling this method if you have more than 1 objects still works with 1
//object too.
private void removeObject(){
int len = myObjects.size();
for(int i = 0;i<len; i++){
Objects object = myObjects.get(i);
myObjects.remove(object);
}
}

when object will be eligible for garbage collecion

A method given to me and asked, when it will be eligible for Garbage Collection, i mean at which line. I believe both o and oa are eligible for garbage collection. Since, they are set to null. Please correct me, if i'm wrong. But, the question was, when it will be eligible for gc, i mean at which line. ?
public Object m() {
Object o = new Float(3.14F);
Object[] oa = new Object[1];
oa[0] = o; /* Line 5 */
o = null; /* Line 6 */
oa[0] = null; /* Line 7 */
return o; /* Line 8 */
}
Please anyone explain. ?
Let us walk through the code:
1) o = new Float();
2) oa = new Object[];
at this point we have 2 objects.
3) oa[0] = o;
at this point oa[0] holds the reference of o.
4) o = null;
o is still being referenced by oa[0]
5) oa[0] = null
o now has zero references.
6) return o;
o is null.
Line 7 is where the GC eligibility happens for o. oa is not eligible for GC until the function exits.
In general, an object is only eligible for GC when there are no references left to it. Be very careful when dealing with a String as there is a special place called the String pool. So the following code:
void foo()
{
String s = "foo";
s=null;
return s;
}
At no point is s guaranteed to be eligible in the function.
Question from comments
one question, you said..oa is not eligible for GC until the function
exits. but, before the return o, oa set to be null and it nowhere
referred too
Answer:
oa is not set to null. What gets set to null is the object at oa[0]
(the first index of oa). If the line was oa = null that would be true,
and irrespective of the only item in oa being null, does not in fact
make the wrapper (in this case an array) null. Similar to having a
List and nulling out all of its elements does not make the List null.
Java is allowed to do certain optimizations, so an optimizing JIT that reasons only about local-effects could simplify this code to
public Object m() {
//Object o = // o does not participate in any externally visible side-effect
new Float(3.14F); // Available for collection as soon as ctor finishes.
//Object[] oa = new Object[1]; // Array ctors are known not to have side-effects, and oa does not participate in a side-effect or result that is visible outside the method.
//oa[0] = o; /* Line 5 */ // Side-effect not visible.
// o = null; /* Line 6 */ // Side-effect not visible.
//oa[0] = null; /* Line 7 */
//return o; /* Line 8 */ // Eliminated by inlining.
return null; // Type-analysis proves that this method can only return null.
}
Don't assume that assignments of local variables to null actually happen in long-lived method calls.
Garbage collection is eligible when no reference to that object exists any longer, but it can be important to note that GC is not guaranteed to run at that time, so technically the memory can be allocated.
oa[0] refers to the object, so when you set it to null at line 7, no reference to that object exists any longer, so it is eligible for GC.
As pointed out on comments, oa, the array itself, is still around until the method is done executing, i.e. after line 8 executes. It is local to the lifetime of the method m(), so it will be eligible for GC when m() returns from execution.
Please correct me, if i'm wrong. But, the question was, when it will be eligible for gc, i mean at which line. ?
The question is nonsensical or based upon an over-simplified model of garbage collection. Garbage collectors act at run-time on the available representation which means tracing reachability from global roots including the registers, stack and global variables. There is no correspondance with high-level source code so it does not make sense to ask about line numbers. In reality, the compiler will mangle your code beyond all recognition before the GC runs.
AFAIK, Java uses the Mark-And-Sweep algorithm. The GC runs in a separate thread over the heap repeatedly.
If a certain reference variable(or object) goes out of scope, its marked for deletion and sweeped off when appropriate(or overwritten).
Also whenever the variable is set to null, that is when the reference count object becomes unreachable by static references and other threads, that is when its reference no longer exists, its marked for deletion again.
Line7 in your code is where it will be marked for deletion.

Categories

Resources