Skip to content
Advertisement

Memory Leak Example -references and objects [closed]

I have the below method.Suppose i call A.m1() 10,000 times from class B. So all 10,000 MyObj objects will be garbage collected as their scope is only within the m1() method. There is no memory leak?

class A {
    String m1() {
        MyObj obj = new Mybj();
    }
}

And i call it below

class B {
    void m2() {
        String s = classAObj.m1();
    }
}

Advertisement

Answer

The references created in the method are eventually garbage collected when they go out of scope. But it doesn’t necessary happen immediately.

Here is a demo that shows that the references are collected. But first some terms.

  • hard reference – A normal reference to an object that will be around
    until it is garbage collected. These are the typical instance values resulting
    from object creation.
  • weak references – references that point to the same object as a hard reference.
    When a hard reference is garbage collected, the associated weak references are also collected.

How this works.

  • The method m1 is called n times, each time creating a weak reference of an instance of A and returning it.
  • This is then added to a list.
  • Once the hard references are garbage collected, the weak references that refer to the same objects will also be collected
  • The weak reference will then return null when trying to retrieve its associated
    object.
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public class GarbageCollection {
    
    public static void main(String[] args) {
        // get out of static context
        new GarbageCollection().start();
    }
    public void start() {
        
        int n = 10_000;
        List<WeakReference<A>> weak = new ArrayList<>();

Create n weak references of A by calling m1 and returning the reference. Then it add to the List.

        for (int i = 0; i < n; i++) {
            WeakReference<A> wk = m1();
            weak.add(wk);
        }

Now iterate thru the List of weak references to see how many are null. Zero is expected
since the garbage collector has not yet run. All of those A allocations created in m1 are still lurking around in the heap.

        int count = 0;
        for (WeakReference<A> wk : weak) {
            if (wk.get() == null) {
                count++;
            }
        }
       
        System.out.println(count); // probably zero

Now repeat the same process but explicitly invoke the garbage collector.

        count = 0;
        System.gc();
        for (WeakReference<A> wk : weak) {
            if (wk.get() == null) {
                count++;
            }
        }

At this point, count should be non-zero (or possibly n for small values of n) to
show some or all of the objects have been collected.

        System.out.println(count);
    }
    
    public WeakReference<A> m1() {
       A a = new A();
       return new WeakReference<>(a);
    }
}

class A {
}

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement