When i initialize the StringBuffer constructor with Integer.MAX_VALUE it throws OutOfMemoryError
and when i add 16 to it it throws NegativeArraySizeException
public class Test {
public static void main(String[] arg) {
StringBuffer sb = new StringBuffer(Integer.MAX_VALUE + 16);
sb.append("A");
}
}
Can some one help me understand this behavior?
You have actually asked two entirely different questions here, so they must be addressed separately.
1. Why does new StringBuffer(Integer.MAX_VALUE)
throw an OutOfMemoryError
?
The StringBuffer
constructor tries to instantiate an array of char
, whose size is the value that you pass. So you're implicitly trying to instantiate an array of size Integer.MAX_VALUE
. There are two reasons why you might get an OutOfMemoryError
from instantiating an array.
The first reason is that you genuinely don't have enough heap space. Without knowing what else is going on in your program, or what your heap settings are, it's impossible for me to tell whether that might be happening for you. But you can choose the maximum heap size for your JVM when you start it up, with the -Xmx
option. Obviously, you'd need to set it to several gigabytes to get this to work (for example -Xmx8g
), assuming your computer has enough RAM.
The second reason for an OutOfMemoryError
when instantiating an array is that you've exceeded the maximum array size. That's definitely happening here. The maximum array size is not defined by the Java Language Specification, and it varies from JVM to JVM. In most modern JVMs, the maximum array size is Integer.MAX_VALUE - 2
, but there are JVMs in which the maximum is Integer.MAX_VALUE - 5
or Integer.MAX_VALUE - 8
. In any case, Integer.MAX_VALUE
is over the limit for sure.
2. Why does new StringBuffer(Integer.MAX_VALUE + 16)
throw a NegativeArraySizeException
?
This is to do with integer arithmetic in Java. Any int
value has to be between Integer.MIN_VALUE
and Integer.MAX_VALUE
. Also, when you add two int
values, the answer is guaranteed by the Java Language Specification to be an int. Therefore, when you evaluate
Integer.MAX_VALUE + 16`, you're not going to get the mathematically correct answer. In fact, what Java does is to work mod 232. Another way of looking at it is that the JVM will add or subtract multiples of 232 to bring the answer within the correct range.
That means that the value of Integer.MAX_VALUE + 16
will actually be numerically equal to Integer.MAX_VALUE + 16 -
232, which is a large negative number. As I mentioned earlier, the StringBuffer
constructor tries to instantiate an array whose size is the value that you pass. This attempt to instantiate an array of negative size gives you your NegativeArraySizeException
.