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

ArrayDeque loses its invariant on OutOfMemoryError in addFirst() or addLast()

XMLWordPrintable

      ADDITIONAL SYSTEM INFORMATION :
      Windows 10 x86_64, Java(TM) SE Runtime Environment (build 21.0.5+9-LTS-239)

      A DESCRIPTION OF THE PROBLEM :
      When the OutOfMemoryError occurs in addFirst() / addLast() of java.util.ArrayDeque, this deque has the first element and the last element, but it's empty by testing ArrayDeque.isEmpty()!

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      >jdk-21.0.5\bin\java -Xmx64m -DtestLast=true ArrayDequeInvariantMissedOnOOM
      Exception in thread "main" java.lang.AssertionError: ArrayDeque invariant lost!
              at ArrayDequeInvariantMissedOnOOM.main(ArrayDequeInvariantMissedOnOOM.java:36)
      Caused by: java.lang.OutOfMemoryError: Java heap space
              at java.base/java.util.Arrays.copyOf(Arrays.java:3482)
              at java.base/java.util.ArrayDeque.grow(ArrayDeque.java:148)
              at java.base/java.util.ArrayDeque.addLast(ArrayDeque.java:306)
              at ArrayDequeInvariantMissedOnOOM.main(ArrayDequeInvariantMissedOnOOM.java:29)

      >jdk-21.0.5\bin\java -Xmx64m -DtestLast=false ArrayDequeInvariantMissedOnOOM
      Exception in thread "main" java.lang.AssertionError: ArrayDeque invariant lost!
              at ArrayDequeInvariantMissedOnOOM.main(ArrayDequeInvariantMissedOnOOM.java:36)
      Caused by: java.lang.OutOfMemoryError: Java heap space
              at java.base/java.util.Arrays.copyOf(Arrays.java:3482)
              at java.base/java.util.ArrayDeque.grow(ArrayDeque.java:148)
              at java.base/java.util.ArrayDeque.addFirst(ArrayDeque.java:289)
              at ArrayDequeInvariantMissedOnOOM.main(ArrayDequeInvariantMissedOnOOM.java:30)


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      ok.
      ok.
      ACTUAL -
      Exception in thread "main" java.lang.AssertionError: ArrayDeque invariant lost!
              at ArrayDequeInvariantMissedOnOOM.main(ArrayDequeInvariantMissedOnOOM.java:36)
      Caused by: java.lang.OutOfMemoryError: Java heap space
              at java.base/java.util.Arrays.copyOf(Arrays.java:3482)
              at java.base/java.util.ArrayDeque.grow(ArrayDeque.java:148)
              at java.base/java.util.ArrayDeque.addFirst(ArrayDeque.java:289)
              at ArrayDequeInvariantMissedOnOOM.main(ArrayDequeInvariantMissedOnOOM.java:30)

      ---------- BEGIN SOURCE ----------
      import java.util.ArrayDeque;
      import java.util.List;
      import java.util.ArrayList;

      class ArrayDequeInvariantMissedOnOOM {
          
          static final boolean TEST_LAST = Boolean.getBoolean("testLast");
          
          public static void main(String[] args) {
              // Prepare data for eliminating `Integer` allocation interference
              final List<Integer> data = new ArrayList<>();
              for (int i = 0; i <= Integer.MAX_VALUE; ++i) {
                  try {
                      data.add(i);
                  } catch (OutOfMemoryError e) {
                      break;
                  }
              }
              // Release some memory for the real test
              for (int i = 0; i < data.size() >> 2; ++i) {
                  data.remove(data.size() - 1);
              }
              
              // Do the real test of ArrayDeque
              final ArrayDeque<Integer> q = new ArrayDeque<>();
              for (int i = 0; i < data.size(); ++i) {
                  final Integer n = data.get(i);
                  try {
                      if (TEST_LAST) q.addLast(n);
                      else q.addFirst(n);
                  } catch (OutOfMemoryError e) {
                      final Integer first = q.getFirst();
                      final Integer last = q.getLast();
                      if (first != null && last != null && q.isEmpty()) {
                          // Here this queue invariant lost!
                          throw new AssertionError("ArrayDeque invariant lost!", e);
                      }
                      break;
                  }
              }
              
              System.out.println("ok.");
          }
          
      }

      ---------- END SOURCE ----------

      FREQUENCY : always


            smarks Stuart Marks
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated: