package com.e2u.gc; public class CircularReference { private static boolean isTestThreadAlive = true; private static int counter = 0; private static Object dummyRef = new Object(); public static void test1() { ClassB cb = null; cb = new ClassB(new ClassA()); monitorGC(); cb = null; monitorGC(); new ClassB(new ClassA()); monitorGC(); System.out.println("\nBefore exit test1 method"); } public static void test2() { { Node a = new Node("a", null), b = new Node("b", a), c = new Node("c", b); a.next = c; c.extension = dummyRef; b.extension = dummyRef; a.extension = dummyRef; } monitorGC(); System.out.println("\nBefore exit test2 method"); } public static void test3() { { Node a = new Node("A", null), b = new Node("B", a), c = new Node("C", b); a.next = c; a = null; b = null; c = null; } monitorGC(); System.out.println("\nBefore exit test3 method"); } private static void monitorGC() { System.out.println("\nGC: Before " + (++counter)); System.gc(); System.out.println("GC: After " + counter); } private static void runTestCaseInThread() { Thread t = new Thread(new Runnable() { public void run() { test1(); test2(); test3(); isTestThreadAlive = false; } }, "TheTest"); t.start(); } /* * @param args */ public static void main(String[] args) { runTestCaseInThread(); while (isTestThreadAlive) { try { Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } } System.out.println("\n\nMain Thread exit"); } } class Finalizable { public void finalize() { String className = getClass().getSimpleName(); String currentThreadName = Thread.currentThread().getName(); System.out.println(className + " " + this + " finalized, Current Thread = " + currentThreadName); try { super.finalize(); } catch (Throwable e) { e.printStackTrace(); } } } class ClassA extends Finalizable { private ClassB refB; public ClassA() { refB = null; } public void setRefB(ClassB refB) { this.refB = refB; } } class ClassB extends Finalizable { private ClassA refA; public ClassB(ClassA ca) { refA = ca; refA.setRefB(this); } } class Node extends Finalizable { public Object value; public Node next; public Object extension = null; public Node(Object o, Node n) { value = o; next = n; } public String toString() { return "Node " + value; } }