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

If the system runs out of memory so there isn't 8 bytes left, Java will hang

    XMLWordPrintable

    Details

    • Subcomponent:
    • CPU:
      sparc
    • OS:
      generic

      Description

      If the system runs out of memory so there isn't 8 bytes left, Java will hang.

      This is because there is a potential loop between SignalError and newobject
      in classruntime.c..

      1. The system runs out of memory trying to allocate some object.
      2. Calls SignalError to report the problem.
      3. SignalError tries to allocate the exception object, calling newobject.
      4. newobject fails also, so calls SignalError. Go to step 2.

      There is code in SignalError that expects newobject to return null if
      it is out of memory, the SignalError will use a preallocated exception object,
      but we don't get that far.

      Note that Java doesn't hang every time it runs out of memory because the
      exception object is smaller than the average size object, so the newobject
      call in step 4 usually succeeds even when step 1 fails..

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

      /**
        * A small generic test object that supports a linked list
        */
      class TestObj {
        TestObj next;

        public static final int OBJECT_SIZE = 2; // words, including headerbut not handle.

        public TestObj() {
          next = null;
        }

        public TestObj(TestObj next) {
          this.next = next;
        }

        public final int length() {
          int len = 0;
          for (TestObj link = this; link != null; link = link.next) {
            len++;
          }
          return len;
        }
      }


      /**
        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);
      }

      /** Create lots of small objects until we run out of memory.
         In a handle-based VM this will test expanding the handle space
         more than the object space. In other systems small and large
         objects may be allocated differently.
       */
      class GCTest02 extends AbstractGCTest {

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

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

        void doTest(String[] args) {
          gc(); // gc now, to prime the system
          
          TestObj head = new TestObj();
          TestObj tail = head;
          int count = 0;

          try {
            while (true) {
      head = new TestObj(tail);
      tail = head;

      count++;
      if (count == 10000) {
      out.println("Allocated 10,000 objects ");
      count = 0;
      }
            }
        } catch (OutOfMemoryError e) {
            head.next = null;
            tail.next = null;
            head = null;
            tail = null;
            gc();
            out.println("Ran out of memory as expected");
          } catch (Exception e) {
            head.next = null;
            tail.next = null;
            head = null;
            tail = null;
            gc();
            out.println("Unexpected exception occurred:");
            e.printStackTrace();
            passed = false;
          }
        }
      }

        Attachments

          Issue Links

            Activity

              People

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

                Dates

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: