On 05/06/2013 10:02 AM, Thomas Schatzl wrote:
I mean, if we fix this issue as you suggested (I am not against that, it
looks reasonable), I would not know what to do with the test program
except file another bug against the very same component with the same
problem, with the same fix suggestion.

Hi Thomas,

If you want a simple reproducer for OOME in ReferenceHandler's Object.wait(), here is one:


public class OOMEInReferenceHandler {

    static Object[] fillHeap() {
        Object[] first = null, last = null;
        int size = 1 << 20;
        while (size > 0) {
            try {
                Object[] array = new Object[size];
                if (first == null) {
                    first = array;
                }
                else {
                    last[0] = array;
                }
                last = array;
            }
            catch (OutOfMemoryError oome) {
                size = size >>> 1;
            }
        }
        return first;
    }

    public static void main(String[] args) throws Exception {
        ReferenceQueue<Object> refQueue = new ReferenceQueue<Object>();
        Object referent = new Object();
WeakReference<Object> weakRef = new WeakReference<Object>(referent, refQueue);

        ThreadGroup tg = Thread.currentThread().getThreadGroup();
        for (ThreadGroup tgn = tg;
             tgn != null;
             tg = tgn, tgn = tg.getParent());

        Thread[] threads = new Thread[tg.activeCount()];
        Thread referenceHandlerThread = null;
        int n = tg.enumerate(threads);
        for (int i = 0; i < n; i++) {
            if("Reference Handler".equals(threads[i].getName())) {
                referenceHandlerThread = threads[i];
            }
        }

        if (referenceHandlerThread == null) {
throw new IllegalStateException("Couldn't find Reference Handler thread.");
        }

        Object waste = fillHeap();

        referenceHandlerThread.interrupt();

        Thread.sleep(1000L);
        waste = null;
        referent = null;
        System.gc();
        Thread.sleep(1000L);

        System.out.println("weakRef.get() = " + weakRef.get());
        System.out.println("refQueue.poll() = " + refQueue.poll());
    }
}



... just run it with some low heap setting like -Xmx128m or so. It doesn't need to be G1 garbage collector. Default will do.

This prints on my computer:

Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Reference Handler"
weakRef.get() = null
refQueue.poll() = null


Regards, Peter



Regards, Peter

Reply via email to