Reputation: 7084
What objects are available for garbage collection at the time of the call System.gc()
and why?
public class GCTest {
static class A {
private String myName;
public A(String myName) {
this.myName = myName;
}
}
public static void main(String[] args) {
A a1 = new A("a1");
A a2 = new A("a2");
ArrayList list = new ArrayList();
list.add(a1);
A[] mas = new A[2];
mas[0] = a2;
a2 = a1;
clear(mas);
a1 = null;
a2 = null;
System.gc();
// some code
...
}
private static void clear(A[] mas) {
mas = null;
}
}
if object == null
it becomes a garbage or not?
I think a1
, a2
and mas
are available for garbage collection at the time of the call System.gc()
because it state null. or I'm wrong?
Upvotes: 3
Views: 120
Reputation: 8211
The object created by new A("a1"), new A("a2") and mas was not garbage collected when you call System.gc()
.
Any object referenced directly or indirectly by Threads are not available for gc. The thread is running this method, so local variables would be kept.
Using the object created by new A("a1")
(let's call it A1
) as an example, .
In the moment of System.gc() is run, list
referencing object A1
in its internal structure, therefore it is not garbage collected even though it is not referenced in a1
.
Upvotes: 0
Reputation: 72844
None will be eligible for GC:
ArrayList
is still reachable and references a1
.a2
and a1
refer to the same object.clear
will not actually clear the array mas
passed from main
.Below is an illustration of the objects in memory when GC is invoked:
Upvotes: 1
Reputation: 200138
The only specified rule regarding object reachability is as follows (§12.6.1):
A reachable object is any object that can be accessed in any potential continuing computation from any live thread.
Examining your code it is quite clear that no object can be accessed in any potential continuing computation. No reference to any of them will exist after main
completes; furthermore System.gc()
is the last statement in the program and that statement's computation will not access those or any other objects (it has no semantics at all at the Java level). Therefore all objects are in fact unreachable at that point, whether the actual implementation of garbage collection realizes that or not.
Upvotes: 1
Reputation: 234795
First, your program variables are never "available for garbage collection". Only objects are collected by the GC and program variables are references to objects, not objects themselves. (The common terminology in referring to Java variables confuses this point.)
Second, none of the objects referenced by a1
, a2
, or mas
are going to be GC'ed. This is despite the fact that a1
and a2
have been set to null
. This is because references to those objects are still reachable through either list
or mas
. Why is the object referenced by a2
still reachable through mas
even after calling clear()
? Because you cannot change the value of the variable mas
in main()
by passing the variable to the method clear()
. All you are doing in that method is changing the formal parameter (also named mas
), which is a separate variable from the local variable in main()
. Java is strictly pass by value. However, when it comes to objects, what's always being passed is a reference.
In general, the rule is that objects are GC'ed only if the objects are unreachable from any program variable, either directly or indirectly.
Upvotes: 7
Reputation: 691635
Nothing is available to GC at this time:
list
) referencing the ArrayList containing the object initially referenced by a1
(the one with the "a1" string inside)mas
) referencing the array containing the object initially referenced by a2
(the one with the "a2" string inside)Note that your method
private static void clear(A[] mas) {
mas = null;
}
does nothing.
Java is pass by value. So when calling this method, a copy of the reference to the array is created and passed to the method. The method then assigns null to the copy of the original reference, leaving the original reference untouched.
See Is Java "pass-by-reference" or "pass-by-value"? for more explanations.
Upvotes: 2