Possible WeakReference Bug

Jesse Rosenstock jmr@ugcs.caltech.edu
Mon Nov 18 12:43:00 GMT 2002


I think I may have found a bug with WeakReference, but I want to make sure
I understand how they're supposed to work before I submit a PR.

It seems that the WeakReference is being enqueued even though the
referent is still live and WeakReference.get() returns non-null.

The program is below.  It prints:

Hmm, reclaimed 13/127 @ iter 13
enqueued, but still alive @ index 127
13/127
Hmm, reclaimed 13/129 @ iter 13
enqueued, but still alive @ index 129
13/129
Hmm, reclaimed 13/106 @ iter 13
enqueued, but still alive @ index 106
13/106
...

Is this a bug, or am I misunderstanding WeakReferences?  Also, it seems
that the finalizer is never called, is that expected?

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;

public class WeakRefTest {
    private static final class Cookie {
        final String s;
        final int i;

        public Cookie(String s, int i) {
            this.s = s;
            this.i = i;
        }

        public String toString() {
            return s;
        }

        public void finalize() {
            // System.out.println("finalizing " + s);
        }
    }

    private static boolean GC = false;

    public static void main(String[] args) {
        if (GC)
            System.gc();
        for (int i = 0; i < 100; ++i) {
            final Cookie[] cs = new Cookie[1000];
            final WeakReference[] ws = new WeakReference[cs.length];
            final ReferenceQueue q = new ReferenceQueue();
            for (int j = 0; j < cs.length; ++j) {
                String s = "" + i + "/" + j;
                cs[j] = new Cookie(s, j);
                ws[j] = new WeakReference(cs[j], q);
            }
            if (GC)
                System.gc();
            Reference r;
            while ((r = q.poll()) != null) {
                Cookie c = (Cookie) r.get();
                System.err.println("Hmm, reclaimed " + c + " @ iter " + i);
                if (cs[c.i] == c) {
                    System.err.println("enqueued, but still alive @ index "
                                       + c.i);
                    System.err.println(ws[c.i].get());
                } else {
                    System.err.println("not found, where did it go?");
                }
            }
            if (GC)
                System.gc();
        }
    }
}



More information about the Java mailing list