Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-1265749

Java will hang if a finalizer runs out of memory if finalizer run synchronously

    XMLWordPrintable

Details

    • 1.1
    • sparc
    • generic
    • Not verified

    Description

      Java will hang if a finalizer runs out of memory if finalizer is run synchronously.

      This is probably due to the fix for bug #1255338

      If a finalizer is run synchronously due to low memory, and the
      finalizer itself allocates memory, it may try to run finalizers again.

      The second time will get hung up in the wait loop in runFinalization:

          while (BeingFinalized != NULL) {
              FINALMEQ_WAIT();
           }

      ---------- Test Case -------------------
      import java.io.*;

      /**
        Common base class for gc tests:
      */
      abstract class AbstractGCTest {
        static String TEST_NAME;
        static boolean firstTime = true;
        static boolean passed = true;
        static PrintStream out;
        static Object log;
        
        public boolean run(String[] args, Object log, PrintStream out) {
          AbstractGCTest.log = log;
          AbstractGCTest.out = out;
          
          doTest(args);
          
          analyze();
          
          return passed;
        }
        
        void gc () {
          System.gc();
          firstTime = false;
        }
        
        void test(boolean assertion, int runNo, String message) {
          if (!assertion) {
            passed = false;
            out.println(TEST_NAME + " failed (on run " + runNo +
      "):\\n " + message);
          }
        }
        
        void analyze() {
          if (passed) {
            out.println("--- " + TEST_NAME + " passed.");
          } else {
            out.println("*** " + TEST_NAME + " FAILED.");
          }
        }
        
        abstract void doTest(String[] args);
      }

      class FinalObj07 {
        public FinalObj07() {
          System.out.println("Created " + this);
        }
        
        public void finalize () throws Throwable {
          super.finalize();
          System.out.println("Finalized " + this); // this allocates memory!
        }
      }

      /* Black box test that detects that bug XXXX is fixed:
         That running out of memory while finalizing because we're out
         of memory won't lock up the system.
         
         PASSES if system doesn't lock up. (maybe I should create a timer thread?)
         */
      class GCTest07 extends AbstractGCTest {
        static final int NUM_OBJECTS = 50;

        public static void main (String[] argv) {
          AbstractGCTest.TEST_NAME = "GCTest07";
          GCTest07 t = new GCTest07();

          t.run(argv, System.err, System.out);
        }

        void doTest(String[] args) {
          System.gc(); // gc now, to prime the system
          Object[] roots = new Object[NUM_OBJECTS];
          
          out.println("Creating finalizable objects...");
          for (int i = 0; i < NUM_OBJECTS; i++) {
            roots[i] = new FinalObj07();
          }

          out.println("Use up all memory. This may hang...");
          String str = "This is a ";
          try {
            while (true) {
      str = str + "test. This is a test. This is a test. This is a ";
            }
          } catch (OutOfMemoryError e) {
            str = null;
            /* allow objects to be finalized */
            for (int i = 0; i < NUM_OBJECTS; i++) {
      roots[i] = null;
            }
            roots = null;
            out.println("Ran out of memory as expected");
          }
        }
      }

      Attachments

        Activity

          People

            tlindholsunw Timothy Lindholm (Inactive)
            drwhite Derek White
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: