3

I am working with 2D int arrays in Java, that are square and can have ~30000 elements in a row and column, which means there are 30000^2*4 bytes in the array, which is less than 5GB (and I have much more than 5GB of memory available).

My basic structure of the program is this:

public class A {
    public static void main(String[] args) {
        Graph g = ...; // read from file
        System.out.println(B.computeSomethingBig(g));
    }
}

public class B {
     public static computeSomethingBig(Graph g) {
         int numVertices = g.numVertices();
         System.out.println(numVertices); // ~30000 maximum
         int[][] array = new int[numVertices][numVertices];
         // ... other computations
     }
}

Now, in Eclipse, I am running main in class A with these arguments:

-Xms5g -Xmx10g

I have numVertices print out a value around 30000, and setting the minimum heap size (-Xms) seems more than necessary. However, I get:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
13
  • Do you think you can declare such an array? Commented Aug 22, 2014 at 3:23
  • 30'000 by 30'000???? Commented Aug 22, 2014 at 3:23
  • @usar What do you mean by that? Commented Aug 22, 2014 at 3:23
  • You are declaring an array with 30 000 integers with 30 000 integers inside each of them Commented Aug 22, 2014 at 3:24
  • 1
    @Thilo new T[int_value][int_value] initializes both dimensions (new T[int_value][/*empty*/] would do only first) and @Ryan int is indeed 4 bytes. Creating (only) int[30000][30000] works for me, in 7u55 on x64 with -Xmx4G, and Runtime .totalMemory() - .freeMemory() confirms it uses slightly over 3.6e9 bytes. Commented Aug 22, 2014 at 6:14

2 Answers 2

3

Running the following:

public class A {
        public static void main(String[] args) {
                int numVertices = 30000;
                int[][] array = new int[numVertices][numVertices];
        }
}

without any parameters, ie java A leads to OOM error. Running java -Xms5g -Xmx10g A works. I suspect numVertices is bigger than what you expected. Why don't you output it before allocating to make sure.

Also consider that your Graph, or other objects in the application could be using heap space too.

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

9 Comments

So basically, the heap is only specific to the main method it was called from? and not any method that it calls (maybe in some other class)?
@Ryan No, the Java heap is the space reserved for objects in your application. docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/…
So then why would the solution you have work and not mine? I am creating a 2D array in the same manner, just in a different method.
Also consider a one-dimensional array instead. There is some overhead involved in a two-dimensional array (as opposed to manually mapping coordinated into a one-dimensional array). At these sizes, this may matter.
@jdphenix Interesting - running that gives both InitialHeapSize and MaxHeapSize to be 2^32 (4294967296).
|
1

What you seem to face is the case where no individual area inside heap (such as eden, survivor or old) is big enough to accommodate the data structure you are trying to allocate. For example - your 5G heap can by default be divided as following (note that this is platform specific):

  • Eden 1.5G
  • Two Survivor spaces 0.25G each
  • Old 3G

More fine-grained configuration by tweaking the ratios of the different areas will sort the things out for you.

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.