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
- Previous message: Code review request: JDK-8008670 (partial java.util.stream implementation)
- Next message: Mismatch between JDK and JVM re largest byte array that VM can allocate?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
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
- Previous message: Code review request: JDK-8008670 (partial java.util.stream implementation)
- Next message: Mismatch between JDK and JVM re largest byte array that VM can allocate?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]