Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8248107 | 16 | Jim Laskey | P3 | Resolved | Fixed | team |
A DESCRIPTION OF THE PROBLEM :
Usually when an OutOfMemoryError is thrown for reasons other than the VM having run out of memory, the reason is included as message, e.g.:
new byte[Integer.MAX_VALUE]: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
StringUTF16.newBytesFor(int): java.lang.OutOfMemoryError: UTF16 String size is [X], should be less than 1073741823
However, there are classes which throw OutOfMemoryError instances without message when the resulting array would be too large. This is not really helpful because the documentation of OutOfMemoryError still only says: "Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory" (see also JDK-8210577)
Therefore the user would assume that the JVM ran out of memory, which is not actually the case.
Simply search for calls of the OutOfMemoryError() constructor. At the time of writing this, they are here:
(list probably incomplete)
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/java/lang/AbstractStringBuilder.java#L269
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/java/lang/String.java#L2189
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/java/lang/StringLatin1.java#L360
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/java/lang/StringUTF16.java#L664
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java#L306
- https://github.com/openjdk/jdk/blob/4f02d011b06fbd033071e8d0d02cffb60d2bed49/src/java.base/share/classes/java/util/regex/Pattern.java#L1685
(Possibly consider deprecating the OutOfMemoryError constructor without arguments?)
Note that there also classes which throw OutOfMemoryError with misleading messages:
(list probably incomplete)
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/sun/text/bidi/BidiBase.java#L1352
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/sun/text/bidi/BidiBase.java#L1361
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/sun/text/bidi/BidiBase.java#L1455
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/sun/text/bidi/BidiBase.java#L1777
---------- BEGIN SOURCE ----------
// Requires String.COMPACT_STRINGS = true
int missingToIntMax = 10;
String tooLarge = "a".repeat(Integer.MAX_VALUE - missingToIntMax);
tooLarge.replace("a", "a".repeat(missingToIntMax + 2));
---------- END SOURCE ----------
Usually when an OutOfMemoryError is thrown for reasons other than the VM having run out of memory, the reason is included as message, e.g.:
new byte[Integer.MAX_VALUE]: java.lang.OutOfMemoryError: Requested array size exceeds VM limit
StringUTF16.newBytesFor(int): java.lang.OutOfMemoryError: UTF16 String size is [X], should be less than 1073741823
However, there are classes which throw OutOfMemoryError instances without message when the resulting array would be too large. This is not really helpful because the documentation of OutOfMemoryError still only says: "Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory" (see also JDK-8210577)
Therefore the user would assume that the JVM ran out of memory, which is not actually the case.
Simply search for calls of the OutOfMemoryError() constructor. At the time of writing this, they are here:
(list probably incomplete)
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/java/lang/AbstractStringBuilder.java#L269
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/java/lang/String.java#L2189
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/java/lang/StringLatin1.java#L360
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/java/lang/StringUTF16.java#L664
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/java/util/concurrent/PriorityBlockingQueue.java#L306
- https://github.com/openjdk/jdk/blob/4f02d011b06fbd033071e8d0d02cffb60d2bed49/src/java.base/share/classes/java/util/regex/Pattern.java#L1685
(Possibly consider deprecating the OutOfMemoryError constructor without arguments?)
Note that there also classes which throw OutOfMemoryError with misleading messages:
(list probably incomplete)
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/sun/text/bidi/BidiBase.java#L1352
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/sun/text/bidi/BidiBase.java#L1361
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/sun/text/bidi/BidiBase.java#L1455
- https://github.com/openjdk/jdk/blob/d7ca08a5cc64c8d3941493d98423a49b5bc1b922/src/java.base/share/classes/sun/text/bidi/BidiBase.java#L1777
---------- BEGIN SOURCE ----------
// Requires String.COMPACT_STRINGS = true
int missingToIntMax = 10;
String tooLarge = "a".repeat(Integer.MAX_VALUE - missingToIntMax);
tooLarge.replace("a", "a".repeat(missingToIntMax + 2));
---------- END SOURCE ----------
- backported by
-
JDK-8248107 Several classes throw OutOfMemoryError without message
-
- Resolved
-
- relates to
-
JDK-8230743 StringJoiner does not handle too large strings correctly
-
- Resolved
-
-
JDK-8247373 ArraysSupport.newLength doc, test, and exception message
-
- Resolved
-