Final call Re: RFR: JDK-8230744 Several classes throw OutOfMemoryError without message
Stuart Marks
stuart.marks at oracle.com
Wed Jun 10 22:02:32 UTC 2020
Regarding the wording, I don't think either "implementation limit" or "VM limit"
is correct, at least not in all the cases.
If we were using ArraysSupport.newLength, the error messages are as follows:
1) Actual shortage of heap space. Hotspot generates this:
OutOfMemoryError: Java heap space
2) Requested array size exceeds implementation limit. Hotspot
generates this:
OutOfMemoryError: Requested array size exceeds VM limit
3) Integer wraparound/overflow during size computation.
ArraysSupport.newLength() generates this:
OutOfMemoryError: Required array length too large
For this changeset, we're leaving several places as they are, either using the
*exact arithmetic methods or doing their own checks. OK, we'll save refactoring
to ArraysSupport.newLength for another time. But the resulting OOME message is I
think misleading.
For example, in String.java line 2190, we catch an exception from Math.addExact
or Math.multiplyExact. This occurs if the arithmetic result exceeds the range of
an int. It's less about some implementation or VM limit, but instead the
requested length simply cannot be represented by an int.
Also, while I'm not as allergic to talking about arrays as Martin, in this case
the subsequent code allocates a StringBuilder and not an array. So it is
somewhat odd for this message to refer to an array.
Anyway, instead of
Requested array size exceeds VM limit
I'd suggest this:
Requested size too large
(Or "length" instead of "size". "Length" is more consistent for arrays and
strings, but oddly enough, Hotspot uses "array size".)
I think this wording could apply to String.java, StringLatin1.java,
StringUTF16.java, Pattern.java, UnsyncByteArrayOutputStream.java, and
ByteArrayChannel.java. I guess we could try to provide a customized message for
each area, but that wouldn't seem to me to add much value.
I'm not entirely sure what's going on in AbstractStringBuilder.java. It uses
ArraysSupport.newLength(), which should either return an in-range value or
throw. I don't understand why the code in ASB.newCapacity() is checking length
against Integer.MAX_VALUE and throwing again. This shouldn't happen by the spec
of AS.newLength(). I think that check (lines 258-259) can simply be removed.
s'marks
On 6/10/20 10:22 AM, Roger Riggs wrote:
> Hi Jim,
>
> In Unsafe.java: 632: the "Unable to allocate 98494837395: doesn't read very well.
> Please add " bytes" to the end.
>
> I would probably drop "array" from all the messages but at least in the String*
> cases.
> As Martin notes, the array is an implementation detail.
> (And i still prefer "implementation limit" over "VM limit".
>
> Thanks, Roger
>
>
>
> On 6/10/20 12:33 PM, Jim Laskey wrote:
>>
>>> On Jun 130, 2020, at 1:15 PM, Martin Buchholz <martinrb at google.com> wrote:
>>>
>>> I took a look at PriorityBlockingQueue.
>>>
>>> Part of converting to ArraysSupport involves deleting the local orphan
>>> MAX_ARRAY_SIZE; that needs to be done.
>> Removed.
>>
>>> ---
>>> It looks like
>>> newCap > oldCap
>>> is always true, so we should delete the test?
>>> if (newCap > oldCap && queue == array)
>>> ---
>> If oldCap == MAX_ARRAY_SIZE wouldn't newCap == oldCap
>>
>>
>>> In Pattern.java I see
>>> + throw new OutOfMemoryError("Requested array size exceeds
>>> VM limit");
>>>
>>> That wording doesn't seem useful to me - the use of an array is an
>>> implementation detail, and the user didn't __request__ it.
>>>
>>> Better seems the wording in ArraysSupport
>>> throw new OutOfMemoryError("Required array length too large");
>>> but if we're going to the trouble of composing a custom detail
>>> message, I'd try harder to find one meaningful to the user of the API,
>>> something like "pattern too large"
>> Done and done.
>>
>> Thank you.
>>
>>
>>
>>> On Wed, Jun 10, 2020 at 5:15 AM Jim Laskey <james.laskey at oracle.com> wrote:
>>>> Will push if no comments by EOB.
>>>>
>>>>> On Jun 8, 2020, at 2:22 PM, Jim Laskey <james.laskey at oracle.com> wrote:
>>>>>
>>>>> Revised to use a consistent error message. Modified AbstractStringBuilder
>>>>> and PriorityBlockingQueue to use ArraysSupport.newLength(). Didn't modify
>>>>> ByteArrayChannel and UnsyncByteArrayOutputStream since those changes would
>>>>> require changes to module exporting.
>>>>>
>>>>> webrev: http://cr.openjdk.java.net/~jlaskey/8230744/webrev-03/index.html
>>>>> <http://cr.openjdk.java.net/~jlaskey/8230744/webrev-03/index.html>
>>>>>
>>>>>
>>>>>> On Jun 3, 2020, at 11:24 AM, Jim Laskey <james.laskey at oracle.com> wrote:
>>>>>>
>>>>>> It's not the goal or role of this bug to fix the wrongs of the past,
>>>>>> merely add error messages to the exceptions. I raised the discussion as an
>>>>>> issue. Clearly there is a correct path to follow. If you think more effort
>>>>>> is required then file a bug. :-)
>>>>>>
>>>>>> Cheers,
>>>>>>
>>>>>> -- Jim
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>> On Jun 2, 2020, at 7:13 PM, Stuart Marks <stuart.marks at oracle.com> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 6/2/20 6:52 AM, Jim Laskey wrote:
>>>>>>>> Revised to reflect requested changes.
>>>>>>>> http://cr.openjdk.java.net/~jlaskey/8230744/webrev-01/index.html
>>>>>>>> <http://cr.openjdk.java.net/~jlaskey/8230744/webrev-01/index.html>
>>>>>>> On this, if all you're doing is changing exception messages, then I don't
>>>>>>> care very much, modulo concerns about wording from others. If you start
>>>>>>> to get into changing the growth logic (like the Math.addExact stuff) then
>>>>>>> please see my message on the related thread, "Sometimes constraints are
>>>>>>> questionable."
>>>>>>>
>>>>>>> Thanks,
>>>>>>>
>>>>>>> s'marks
>
More information about the core-libs-dev
mailing list