ip696
ip696

Reputation: 7084

the work of the garbage collector in Java

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

Answers (5)

Derek Fung
Derek Fung

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

M A
M A

Reputation: 72844

None will be eligible for GC:

  1. The ArrayList is still reachable and references a1.
  2. Both a2 and a1 refer to the same object.
  3. Most importantly, since Java is pass-by-value, the method clear will not actually clear the array mas passed from main.

Below is an illustration of the objects in memory when GC is invoked:

enter image description here

Upvotes: 1

Marko Topolnik
Marko Topolnik

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

Ted Hopp
Ted Hopp

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

JB Nizet
JB Nizet

Reputation: 691635

Nothing is available to GC at this time:

  • you still have a reference (list) referencing the ArrayList containing the object initially referenced by a1 (the one with the "a1" string inside)
  • you still have a reference (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

Related Questions