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

VM crashes when heap is exhausted

XMLWordPrintable

    • kestrel
    • generic, x86
    • generic, windows_nt



      Name: dkC59003 Date: 06/09/99



      Classic VM releases included into JDK 1.2.2T, 1.2.2U, 1.3F, and 1.3G
      crash under the HotSpot test:
          ${TESTBASE}/src/nsk/stress/memory/memleak004
      where:
          TESTBASE=/net/sqesvr/vsn/testbase/testbase_nsk
      is location of Novosibirsk testbase for HotSpot.

      JDK versions 1.1, 1.1.x, and 1.2 do not crash, but JDK versions 1.1.5,
      1.1.6, 1.1.7, 1.1.8, and 1.2 fail to pass "memleak004" under Win32 with JIT
      on, though due to another JVM problem - slow garbage collector performance.
      (I am going to file a separate bug against GC poor performance.) Finally,
      JDK 1.0.2 crashes while trying to execute "memleak004" under Win32, and
      fails on Sparc.

      I have tried "memleak004" on the following computers:
      - 350MHz Pentium-II, RAM 128Mb, Windows NT 4.0 SP3
      - 166MHz Sparc Ultra-1, RAM 128Mb, Solaris 2.5.1

      Both Sparc and Win32 versions of JDK 1.2.2 and 1.3 classic VM do crash:
      - Sparc versions crash both with JIT on and with JIT off.
        When JIT is on, both green and native threads VM crash on Sparc.
      - Win32 versions crash both with JIT on and with JIT off.

      Sparc versions suffer "Segmentation Fault" and return exit
      status=-2147483642 or status=-2147483637.

      Win32 crashes look like the following:

          When testing JDK 1.2.2T or 1.2.2U,
          Visual Studio flashes the popup window:
              java.exe - Application Error
              The instruction at "0x5035a224" referenced to memory
              at "0x00000000". The memory could not be "read".
              Press OK to continue
              Press CANCEL to start debugger
          Debugger popups the window:
              Unhandled exception in java.exe (JVM.DLL):
              0xC0000005: Access Violation
          and shows the following portion of code:
              5035A220 mov eax,dword ptr [ecx]
              5035A222 pop esi
              5035A223 pop ebx
           ==>5035A224 mov eax,dword ptr [eax]

          When testing JDK 1.3F or 1.3G,
          Visual Studio flashes the popup window:
              java.exe - Application Error
              The instruction at "0x5049f4a2" referenced to memory
              at "0x00000000". The memory could not be "read".
              Press OK to continue
              Press CANCEL to start debugger
          Debugger popups the window:
              Unhandled exception in java.exe (JVM.DLL):
              0xC0000005: Access Violation
          and shows the very similar portion of code:
              5049F49E mov eax,dword ptr [ecx]
              5049F4A0 pop esi
              5049F4A1 pop ebp
           ==>5049F4A2 mov ecx,dword ptr [eax]

      So, I believe that this is the same bug in classic VM included into
      JDK 1.2.2 and 1.3

      Note, that HotSpot 1.3 betaD-betaG (the last is built into JDK 1.3G)
      also fail under "memleak004" test due to similar HotSpot bug:
          #4239828 (P1/S4) 1.3c1: VM crashes when heap is exhausted
      which is revealed by the test:
          ${TESTBASE}/src/nsk/stress/memory/memleak003

      The test "memleak004" is almost the same as "memleak003", but
      "memleak004" tries to allocate additional (rather small) amount
      of memory just after it releases all the memory it has allocated
      before.

      JDK 1.2.2 and 1.3 classic VM pass "memleak003", so their failures under
      "memleak004" also seems to imply slow performance of garbage collector.
      Look at the HotSpot bug:
          #4239841 (P1/S5) 1.1: poor garbage collector performance
      revealed by the test:
          ${TESTBASE}/src/nsk/stress/memory/memleak001

      Following is the source of memleak004.java:

      /* @(#)memleak004.java 1.1 99/05/26
       * Copyright 99/05/26 Sun Microsystems, Inc.
       */

      // package javasoft.sqe.tests.stress.memory.memleak004;

      import java.io.*;

      /**
       * This test eats all available memory, then releases it and tries to
       * allocate another (rather small) amount of memory.
       *
       * <p>Some JVM fail to allocate the last amount of memory. It looks
       * like slow performance prevents garbage collector from recycling
       * memory just released.
       *
       * <p>See also the tests:
       * <br>&nbsp;&nbsp;<code>src/nsk/stress/memory/memleak001</code>
       * <br>&nbsp;&nbsp;<code>src/nsk/stress/memory/memleak003</code>
       *
       * @author Eugene I. Latkin
       */
      public class memleak004 {
          /**
           * Re-call to the method <code>run(args,out)</code> to make this
           * test similar to JCK tests.
           */
          public static void main (String[] args) {
      int exitCode = run(args,System.out);
      System.exit(exitCode + 95);
      // JCK-like exit status
          };

          /**
           * The test's body. Try to allocate as much memory as possible,
           * then releaseall the memory just allocated, and then try to
           * allocate another (rather small) amount of memory.
           */
          public static int run (String args[], PrintStream out) {
              Booty[] wallet = new Booty[1024];
              int amount = 1024*1024*2;

              for (int count=0; (count<wallet.length) && (amount>1); count++)
                  try {
                      wallet[count] = new Booty(amount);
                  } catch (OutOfMemoryError oops) {
                      amount /= 2;
                  };

              wallet = null;
      System.gc();

      try {
      Booty junk = new Booty(10*1024); // allocate 10Kb
      } catch (OutOfMemoryError foo) {
      return 2; // FAILED
      };

      return 0; // PASSED
          };

          /**
           * Array of the type <code>byte[]</code> intended to be put into
           * a pool of similar arrays in order to detain allocated memory.
           */
          static class Booty {
              byte[] booty;

      /**
               * Consume the given <code>amount</code> of bytes.
               */
              Booty (int amount) {
                   booty = new byte[amount];
              };
          };
      }

      ======================================================================

      Name: dkC59003 Date: 06/09/99



      See also the bug:
          #4245060 (P4/S5) poor garbage collector performance

      ======================================================================

      Name: skT88420 Date: 06/15/99


      Compile (javac Crash2.java) => Run (java Crash2) => Crash :o(

      I've attached the source of a minimal program that causes a crash that seems to be identical to the one that I'm seeing in my application.
      The result is an unrealistic application which causes lots of window resizes (which in itself may be the root of the problem). The application typically runs for anywhere between 1-2 minutes to 20-30 minutes before crashing.
      I get an identical crash from both the standalone JVM (1.2 and 1.2.1) and the same versions of JRE through Netscape 4.0.4.
      The text of the error (paraphrased) is:
      ------------------------------------------
      java (or Netscape).exe - Application Error
      The instruction at 0x5008e67c ref'd memory at 0x05c8f2bc. The memory could not be read...
      ------------------------------------------

      I thought initially that it was a multi-threading issue - my original application generates numerous updates - sometimes 10's a second from a 'background' thread reading from a socket.
      It could be a NT Windows handle problem but it seems too unpredictable - considering how this test program 'hammers' it.
      The randomisation bit to cause more frequent window-resizes *seems* to cause the problem to occur earlier - but it will fail without it.


      import javax.swing.*;
      import javax.swing.event.*;
      import javax.swing.text.*;
      import javax.swing.border.*;

      import java.awt.*;
      import java.awt.event.*;

      public class Crash2 extends JPanel
      {
          public static JFrame frame;

          public Crash2()
      {
      add(m_text);

      m_timer = new Timer(1,
      new
      ActionListener()
      {
      public void actionPerformed(ActionEvent e)
      {
      int i;

      for(i = 0; i < 13; i++)
      {
      m_total++;

      int r = (int)(Math.random() * 50);

      String s = "";

      int j;

      for(j = 0; j < r; j++)
      {
      s += "*";
      }

      if (++m_count > 10)
      {
      m_text.setText("The value of m_total is now " + m_total + " - " + s + "\n");

      m_count = 0;
      }
      else
      {
      m_text.append("The value of m_total is now " + m_total + " - " + s + "\n");
      }
      }
      }
      }
      );

      m_timer.start();
      }

        public static void main(String[] args)
      {
      frame = new JFrame("Crashing :o( Sample");
      Crash swing = new Crash();

      frame.setBounds(0,0,800,500);

      frame.getRootPane().getContentPane().add("Center",swing);

      frame.show();
      }

      JTextArea m_text = new JTextArea(5,5);
      int m_total = 0;
      int m_count = 0;
      Timer m_timer;
      }
      (Review ID: 84369)
      ======================================================================

            hongzh Hong Zhang
            dkhukhrosunw Dmitry Khukhro (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: