java.lang.OutOfMemoryError: Java heap space while

2020-07-11 07:46发布

I am trying to initialise an array of boolean type whose size is a 10 digit integer. It keeps on throwing OutOfMemoryException. I have increased the size of the heap space of eclipse to 1024 from 256. Is there anything that I am missing to do?

int size = 1000000000;
boolean[] primesList = new boolean[size];

7条回答
Summer. ? 凉城
2楼-- · 2020-07-11 07:51

From docs

This data type represents one bit of information, but its "size" isn't something that's precisely defined.

If you consider at least one byte for boolean, that 1000000000 byte , requires 953MB memory for your array.

So that is the only array eating up 953MB of 1024MB, might that causing the problem.

But in a good world this use case won't require I guess :)

查看更多
We Are One
3楼-- · 2020-07-11 08:00

It could be very well due to the following two reasons:

  1. According to this article, JVM does not allocate the entire Xmx amount to your program. The space taken up by one of the survivor spaces is discounted as JVM uses it internally for some bookkeeping or temporary usage. That could be the reason why 1024 MB is not sufficient in this case as your array is already using 954 MB. The survivor space could be over 70 MB. Increasing the Xmx may or may not help as explained in the below point

  2. According to this article, you can have OOM if your data structure is too big for any of the generations in the heap (eden, from/to survivor, old gen). You can use -XX:+PrintGCDetails and see how much each of the generations are getting. So, you have to keep increasing your Xmx until at least one of them (eden, from/to, old gen) is big enough to hold your object or you would have to explicitly set the size of the different heap areas (e.g., -XX:NewSize for Young gen).

查看更多
做个烂人
4楼-- · 2020-07-11 08:01

Use java.util.BitSet, which will pack the bits in one-eighth of the space compared to using a boolean array.

The reason boolean array elements take 1 byte instead of 1 bit is because (most) CPU architectures don't provide the ability to directly read and write individual bits of memory. The smallest unit PCs can manipulate has 8 bits. The JVM could pack the bits together, then to modify a bit it would read the byte, modify it, and write it back, but that does not work if multiple threads are modifying the array simultaneously.

As to your original array, it's 1 billion booleans, one byte each, which is 1 billion bytes or ~954 MB. So a 1024 MB heap ought to be enough (?). Perhaps it can't find a contiguous chunk of memory big enough, or perhaps you have not set the memory parameter correctly. Print the value of Runtime.getRuntime().maxMemory() to find out the maximum heap size that Java is using. For 1024 MB the parameter should be -Xmx1024M.

Final note: As of Java 7 you can use underscores in numbers to make them more readable. So you can write 1_000_000_000 instead of 1000000000.

查看更多
Melony?
5楼-- · 2020-07-11 08:04

You could use an object holder instead, avoiding the need to allocate all the space at once- which may get around the problem if the heap size is large enough. You need a lot of space to hold that many booleans in an array- make sure the min and max size are set for the heap space. Use something like List to only fill up values when needed too. If you really need it as an array there are ways to convert back (Arrays collection in apache commons lets you use Arrays.toPrimitive).

查看更多
成全新的幸福
6楼-- · 2020-07-11 08:04

Boolean arrays are stored as bytes:

https://forums.oracle.com/thread/2550321

I think you need to rethink how you are doing this - creating data structures with sizes in the order of gigabytes is beyond the capabilities of current hardware.

查看更多
做自己的国王
7楼-- · 2020-07-11 08:11

Simply request more heap size, eg -X1500M definitely works. Your array occupies 1000000000 bytes, but you need to request more because Java heap is devided into new + old generations.

查看更多
登录 后发表回答