6

I have a program where I will be using a very large short[] array:

import java.lang.Math;

public class HPTest {

    public static void main(String[] args) {
        int n = 30;
        short[] a = new short[(int)Math.pow(2,n)];
    }
}

As far as I know, a short[] array should use 2 bytes per element, and so an array with 2^30 elements should need about 2 GiB of RAM.

In order to run the program, I therefore tried

java -Xms2000m HPTest

but still got a heap space error. Even at 3000m I got the same error, but at 4000m it worked.

Any ideas as to why I had to go so far above the estimated limit of 2000m?

EDIT: As has been pointed out by many users, I made a very embarrassing error in declaring that a short needs 1 byte rather than 2 bytes. The question then should be why it doesn't suffice with 2000m.

1 Answers1

5

Something this large, will be much happier outside the heap. You would be better off looking in to NIO and using direct byte buffers to back your large Short array. This memory can be kept out of the heap, and away from the mitts of the garbage collector (who may at times feel inclined to want to copy your buffer from one area to the other).

See java.nio.ShortBuffer and start digging from there.

Will Hartung
  • 115,893
  • 19
  • 128
  • 203
  • Thanks! On second thought, I might be able to swtich down to a byte array. Anyway, I will basically be using the array as an array of flags corresponding to different containers of all integers from 0 to 2^30-1. Therefore, as I loop through these integers, I will set the flag at the corresponding index of my short/byte array to a certain value. As far as I can see, I can accomplish this by calling put() on the buffer each time. Would this be very slow? – Alexandre Vandermonde Feb 25 '16 at 19:11
  • Actually, allocations that are this big goes straight to the "Old Gen" pool, and will not be copied around by the garbage collector. I just empirically tested that to be true, and I seem to remember reading that somewhere, but I don't have a reference at this time. – Andreas Feb 25 '16 at 21:29
  • @AlexandreVandermonde If they are just flags, you should make it a `boolean` array, and the JVM may squeeze 8 booleans into a single byte. – Andreas Feb 25 '16 at 21:31
  • @Andreas Could you please elaborate a bit on the "Old Gen" pool. Also, flags may have been an inappropriate term, as my flags are not binary but rather n-ary. – Alexandre Vandermonde Feb 25 '16 at 21:42
  • @AlexandreVandermonde If you want to learn more about Java memory pools, you could read something like this: [Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide](https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/toc.html) – Andreas Feb 25 '16 at 23:40
  • @Andreas I just tried to allocate a ShortBufer of size 2^30 and I still got the same heap space error as I did when I tried to allocate a short array. Did I miss something? – Alexandre Vandermonde Feb 26 '16 at 00:10
  • @AlexandreVandermonde I believe Will was talking about a `ShortBuffer` obtained by calling `ByteBuffer.asShortBuffer()`, on a *direct* `ByteBuffer` mapped to a file. – Andreas Feb 26 '16 at 01:23