JDK-7153247 : Provide public method to insure secure maximum array size
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 7
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2012-03-12
  • Updated: 2021-03-02
Related Reports
Relates :  
Relates :  
Description
A DESCRIPTION OF THE REQUEST :
This method eases the recalculation of insufficient array size.
Some VMs reserve some header words in an array.
Attempts to allocate larger arrays may result in OutOfMemoryError: Requested array size exceeds VM limit
java.lang.System seems to be an appropriate home.


JUSTIFICATION :
Increasing an array is a common task in the JDK.
Exemplary use case: see bug 7153238



---------- BEGIN SOURCE ----------
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

    /**
     * @param old the current size of the array
     * @param size the requested size (must not be bigger than the old size)
     */
    public int secureArraySize(int old, int size) {
        // overflow-conscious code
        assert (size <= old);
        if (size - MAX_ARRAY_SIZE <= 0)
            return size;
        if (++old < 0) // overflow
            throw new OutOfMemoryError
                    ("Required array size too large");
        return (old > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE : MAX_ARRAY_SIZE;
    }

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

Comments
The "MAX_ARRAY_SIZE" value is a guess by the library about a value the JVM can allocate, provided enough heap is available. Hotspot, at least currently, imposes a an actual maximum array size of either MAX_VALUE-2 or MAX_VALUE-3 depending upon whether compressed OOPS are in use. (I'm not sure which is which.) This is for JDK 14 with the default GC, which is currently G1GC. However, this value might vary if a different GC is in use. It might also vary depending on the array's component type. For example, a maximum-sized byte array would occupy about 2^31 bytes, but a maximum-sized long array would occupy about 2^34 bytes. A JVM might impose a maximum limit based on some segment size in bytes, not array size. Further, this problem might become worse when value types are added, so an array's component type conceivably could be even larger than 8 bytes. I'm thus skeptical that there would be a single, global maximum array size. An alternative would be to have something like maxArraySize(Class<?> clazz) but this seems quite obscure. It seems preferable to add this as a private JVM interface and have library code expose array utilities that use it and that are more useful to application code.
13-06-2020