Reputation: 451
I got "java.lang.OutOfMemoryError: Java heap space"
exception while running following code snippet. I have set JVM heap size 8192M
with command set JVM_ARGS="-Xms8192m -Xmx8192m"
.
List<Integer> largeList = new ArrayList<>();
Random rand = new Random();
for(int i=0;i<Integer.MAX_VALUE/2;i++)
{
largeList.add(rand.nextInt(Integer.MAX_VALUE));
}
I think JVM heapsize, I set, is big enough to hold array.
Upvotes: 3
Views: 1415
Reputation: 308001
A List
can only hold objects.
An Integer
object needs at least 4 byte for the actual value and some amount of bytes for various object-related overhead (varies by JVM, but is usually around 16-30 bytes per object).
Integer.MAX_VALUE / 2
is about a billion. So for the data alone (without object overhead) you'd need 4 billion bytes to store the list. That's 4GB. So even if the object overhead was only 4 bytes (very hard to do, and probably not very efficient at runtime), that would already use up all 8GB of your heap (and leave nothing for all of the classes needed to run your code). And that doesn't even include the memory held for the ArrayList
which needs to hold that many references (which are either 8 or 4 bytes, depending on what JVM and which settings you use).
So no, you've not assigned it nearly enough memory.
If you actually need that many int
values, consider using a int[]
which is significantly more memory efficient than that, effectively taking 4 bytes per int
with a small fixed-sized overhead.
Upvotes: 8
Reputation: 328568
When the ArrayList is full, its size is increased by 50% - so the size of your list may be as high as 0.75 * MAX_VALUE = 0.75 * 2^31 = 1.6 billion.
An Integer takes 16 bytes in memory, and each Integer reference takes 4 or 8 bytes in the list. Lets assume 4 here. So your list could take up to 1 billion * 16 + 0.6 billion * 4 (for null entries) = 30 GB in memory.
Upvotes: 4
Reputation: 1171
The size of a int
is 4 bytes, so in theory you'll have more than 4 GB of Integer
s in your heap due to the wrapper's overhead; another point is that ArrayList
changes its size by using Arrays.copyOf()
, so more memory is needed to resize the list itself to ensure its capacity is enough while filling.
Upvotes: 0