(Preliminary) RFC 7038914: VM could throw uncaught OOME in ReferenceHandler thread (original) (raw)

Peter Levart peter.levart at gmail.com
Mon May 6 20:34:26 UTC 2013


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(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



More information about the core-libs-dev mailing list