JDK-8059914 : Cannot allocate array with Integer.MAX_VALUE elements
  • Type: Bug
  • Component: hotspot
  • Sub-Component: gc
  • Affected Version: 7u67,8u20,8u40
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • OS: linux_redhat_6.0
  • CPU: x86
  • Submitted: 2014-10-02
  • Updated: 2022-12-15
  • Resolved: 2014-12-04
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
$ java -version
java version "1.7.0_67"
Java(TM) SE Runtime Environment (build 1.7.0_67-b01)
Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
$ uname -a
Linux pinyon 2.6.32-431.29.2.el6.x86_64 #1 SMP Tue Sep 9 21:36:05 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux


A DESCRIPTION OF THE PROBLEM :
Attempting to allocate an array with Integer.MAX_VALUE or Integer.MAX_VALUE-1 elements results in out of memory error, regardless of heap space. The type of the array elements does not matter. Whether byte, float, or double, all allocations of Integer.MAX_VALUE or Integer.MAX_VALUE-1 elements fail with
   java.lang.OutOfMemoryError: Requested array size exceeds VM limit

This fails in both Java 7 (7u67) and Java 8 (8u20). It works correctly in Java 6 (6u45).

REGRESSION.  Last worked in version 6u45

ADDITIONAL REGRESSION INFORMATION: 
$ java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)





STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile and run the test program, Memory.java.

$ javac Memory.java
$ java -Xmx15g Memory

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Compile and run the test program, Memory.java. Program runs without errors with Java 6u45.

$ javac Memory.java
$ java -Xmx15g Memory
Allocating 2147483642 elements.
Allocating 2147483643 elements.
Allocating 2147483644 elements.
Allocating 2147483645 elements.
Allocating 2147483646 elements.
Allocating 2147483647 elements.
Done allocating.

ACTUAL -
Program fails at Integer.MAX_VALUE-1 elements. Fails with Java 7 and Java 8. Works with Java 6.

$ javac Memory.java
$ java -Xmx15g Memory
Allocating 2147483642 elements.
Allocating 2147483643 elements.
Allocating 2147483644 elements.
Allocating 2147483645 elements.
Allocating 2147483646 elements.
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
	at Memory.main(Memory.java:8)


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
	at Memory.main(Memory.java:8)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
// Test program source file: Memory.java
public class Memory {
  public static void main(String[] args) throws Exception {
    for (int i = Integer.MAX_VALUE-5; i>0; ++i) {
      System.out.println("Allocating "+i+" elements.");
      // Note that the type of allocation is not important. It fails at
      // Integer.MAX_VALUE-1 elements whether byte, float, double, etc.
      Object array = new byte[i];
    }

    System.out.println("Done allocating.");
  }
}

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


Comments
Closing this bug as will not fix since the current code works as designed. This comment comes from JDK-8029587 Background: In the GC code we pass around the size of objects in words as an int. When we add the header size of an object and then convert back from words to bytes we may overflow an int. This can cause crashes and unexpected behavior. By limiting the maximum array length to be (max size - header size) we avoid these issues. For more details see JDK-7110613 and JDK-4718400
04-12-2014

See JDK-8029587 - which is basically the same report for 7u.
17-10-2014

Reproducible as reported with 8u20 and 8u40 build 08 too.
08-10-2014