AssertGC

WeakReference使ったキャッシュとかのテストとかで使ってます。

System.gc()は別にGC走らせなくてもよかったり、いろいろと問題はありますが、インクリメンタルGC以外を指定して下のようなコード書けばほぼOKだと思います。
本気でやるなら、WeakReferenceの回収スレッドとGCを全力で用意する必要があります。

厳密じゃない動作ということで、参考までに。

public class Assert2 {

    private static final int ALLOCATE_SIZE = 65536;
    
    public static void assertGc(WeakReference<?> ref) {
        SoftReference<LinkedList<int[]>> memoryEater1 =
            new SoftReference<LinkedList<int[]>>(new LinkedList<int[]>());
        SoftReference<LinkedList<int[]>> memoryEater2 =
            new SoftReference<LinkedList<int[]>>(new LinkedList<int[]>());
        
        while (true) {
            System.gc();
            if (consumeMemory(memoryEater1)) {
                break;
            }
            if (consumeMemory(memoryEater2)) {
                break;
            }
        }
        
        if (ref.get() != null) {
            throw new AssertionError();
        }
    }
    
    private static boolean consumeMemory(SoftReference<LinkedList<int[]>> eater) {
        LinkedList<int[]> list = eater.get();
        if (list == null) {
            return true;
        }
        list.add(new int[ALLOCATE_SIZE]);
        return false;
    }
}

ポイントは、SoftReferenceを2本用意して、交互にメモリを食いつぶすオブジェクトを追加していく感じです。
1本でやろうとするとスタックにLinkedListがある状態でnew int[] するので、そこでOutOfMemoryが発生する場合があります。

public class Assert2Test {

    /**
     * Test method for {@link Assert2#assertGc(java.lang.ref.WeakReference)}.
     */
    @Test
    public void testAssertGc() {
        Object obj = new String("Hello, world!");
        WeakReference<Object> ref = new WeakReference<Object>(obj);
        
        // keeps only weak references
        obj = null;
        
        Assert2.assertGc(ref);
    }

    /**
     * Test method for {@link Assert2#assertGc(java.lang.ref.WeakReference)}.
     */
    @Test
    public void testAssertGcLeak() {
        Object obj = new String("Hello, world!");
        WeakReference<Object> ref = new WeakReference<Object>(obj);
        
        // keeps strong references
        // obj = null;
        
        Assert2.assertGc(ref); // failure
    }
}

ちなみに、"Hello, world!"ではなくnew String("Hello, world!")にしてるのは、コンスタントプールにStringオブジェクトがリーク?するためです。