8

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];
8
  • 4
    do you seriously need that amount of space? Commented Oct 11, 2013 at 8:10
  • Count first: size * 4 bytes plus other objects. Use Buffer instead Commented Oct 11, 2013 at 8:13
  • @ajozwik Where did you get size*4 bytes? Commented Oct 11, 2013 at 8:13
  • See stackoverflow.com/questions/383551/… Commented Oct 11, 2013 at 8:19
  • 1
    @GarethDavis It might be for generating a prime sieve or for primality testing of arbitrary numbers, which needs a random-access array like this for performance. Commented Oct 11, 2013 at 8:53

7 Answers 7

13

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.

Sign up to request clarification or add additional context in comments.

Comments

3

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 :)

3 Comments

You added a zero there, and a boolean doesn't take one bit, at least in this form.
You miscalculated. There is 10 digit number, not 11.
@ViktorOzerov Yes, you are right, That extra zero has been removed. Thanks for pointing.
1

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.

Comments

0

When starting the JVM you need to pass a -Xmx parameter to set the maximum heap space as higher.

Also note that arrays have a maximum size of Integer.MAX_VALUE

Comments

0

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).

Comments

0

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.

Comments

0

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).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.