Mismatch between JDK and JVM re largest byte array that VM can allocate? (original) (raw)

Srinivas Ramakrishna ysr1729 at gmail.com
Mon Mar 11 23:11:10 UTC 2013


I am looking at code in (for example) ByteArrayOutputStream.java :-

   96     /**

   97      * Increases the capacity to ensure that it can hold at least the

   98      * number of elements specified by the minimum capacity argument.

   99      *

  100      * @param minCapacity the desired minimum capacity

  101      */

  102     private void grow(int minCapacity) {

  103         // overflow-conscious code

  104         int oldCapacity = buf.length;

  105         int newCapacity = oldCapacity << 1;

  106         if (newCapacity - minCapacity < 0)

  107             newCapacity = minCapacity;

  108         if (newCapacity < 0) {

  109             if (minCapacity < 0) // overflow

  110                 throw new OutOfMemoryError();

  111             newCapacity = Integer.MAX_VALUE;

  112         }

  113         buf = Arrays.copyOf(buf, newCapacity);

  114     }

This can result in a request for an array of size Integer.MAX_VALUE (because of line 111 above), see below:-

 2874     /**

 2875      * Copies the specified array, truncating or padding

with zeros (if necessary)

 2876      * so the copy has the specified length.  For all indices that are

 2877      * valid in both the original array and the copy, the

two arrays will

 2878      * contain identical values.  For any indices that are

valid in the

 2879      * copy but not the original, the copy will contain

(byte)0.

 2880      * Such indices will exist if and only if the specified length

 2881      * is greater than that of the original array.

 2882      *

 2883      * @param original the array to be copied

 2884      * @param newLength the length of the copy to be returned

 2885      * @return a copy of the original array, truncated or

padded with zeros

 2886      *     to obtain the specified length

 2887      * @throws NegativeArraySizeException if

newLength is negative

 2888      * @throws NullPointerException if <tt>original</tt> is null

 2889      * @since 1.6

 2890      */

 2891     public static byte[] copyOf(byte[] original, int newLength) {

 2892         byte[] copy = new byte[newLength];

 2893         System.arraycopy(original, 0, copy, 0,

 2894                          Math.min(original.length, newLength));

 2895         return copy;

 2896     }

So the call at line 2892 can cause a request for an array with Integer.MAX_VALUE entries, yet the JVM doesn't give you arrays that large; witness this code in arrayOop.cpp where this will flatten out:-

// Return the maximum length of an array of BasicType. The length can passed // to typeArrayOop::object_size(scale, length, header_size) without causing an // overflow. We also need to make sure that this will not overflow a size_t on // 32 bit platforms when we convert it to a byte size. static int32_t max_array_length(BasicType type) { assert(type >= 0 && type < T_CONFLICT, "wrong type"); assert(type2aelembytes(type) != 0, "wrong type");

const size_t max_element_words_per_size_t =
  align_size_down((SIZE_MAX/HeapWordSize - header_size(type)),

MinObjAlignment); const size_t max_elements_per_size_t = HeapWordSize * max_element_words_per_size_t / type2aelembytes(type); if ((size_t)max_jint < max_elements_per_size_t) { // It should be ok to return max_jint here, but parts of the code // (CollectedHeap, Klass::oop_oop_iterate(), and more) uses an int for // passing around the size (in words) of an object. So, we need to avoid // overflowing an int when we add the header. See CRs 4718400 and 7110613. return align_size_down(max_jint - header_size(type), MinObjAlignment); } return (int32_t)max_elements_per_size_t; }

Is there any plan to fix this mismatch ? May be it's as simple(!) as checking the GC code to make sure it doesn't traffic in int's and fix the code above to return max_jint for the byte array case as well? I have a vague recollection of a bug id already for this, but it's been a while....

Thanks! -- ramki



More information about the core-libs-dev mailing list