23

If I have:

int c[] = new int[10];

and

int a[][] = new int[2][3];

and in generally

an n*m*..*j array

how can I calculate the real memory usage considering also the references variables?

1
  • 2
    Is there a motivation behind getting the "real memory usage" of those arrays? Commented Jun 4, 2010 at 8:53

7 Answers 7

23

I know I'm kinda late to the party, but it's really not extremely hard to compute the memory footprint.

Lets take your first example: int c[] = new int[N];

According to the 64-bit memory model, an int is 4 bytes, so all the elements will be 4*N bytes in size. In addition to that, Java has a 24 bytes array overhead and there's also 8 bytes for the actual array object. So that's a total of 32 + 4 * N bytes.

For a 2 dimensional array: int a[][] = new int[N][M];

It's basically the same just that each element in the first array is another array of size M, so instead of 4 we have 32 + 4 * M, so the total size is 32 + (32 + 4 * M) * N.

It's true that a generalization for D dimensions is pretty complicated, but you get the idea.

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

2 Comments

Where do you get the 24 byte overhead from? I assume the number is for some specific VM.
This was the answer I needed. I'm working on a project where I am going to need a pretty big array, I don't want to break it up into a bunch of disk operations and I need to know the how much memory these objects will consume. Thank you.
19

If you want an accurate answer, you can't. At least not in any easy way. This thread explains more.

The trouble with Bragaadeesh's and Bakkal's answers are that they ignore overhead. Each array also stores things like the number of dimensions it has, how long it is and some stuff the garbage collector uses.

For a simple estimate, you should be fine by using the calculations from the other answers and adding 100-200 bytes.

5 Comments

This answer is correct. There's always overhead due to type/GC information and whatnot. Plus there's the fact that Java doesn't have a true multidimensional array, only jagged arrays, which end up generating quite a bit of that overhead.
how is represented in memory a multidimensional array?
I deleted my answer since I know of no way to calculate the exact size inclusive of overhead.
@xdevel2000: Java does not have multidimensional arrays. Only arrays of arrays.
@Matti Virkkunen: True. The VM still keeps track of how many layers of arrays are nested, so you can't assign an array of chars to an array of arrays of chars.
3

you'll probably get the best approximation from this: http://java.sun.com/javase/6/docs/api/java/lang/instrument/Instrumentation.html#getObjectSize(java.lang.Object)

This article, and this comprehensive one demonstrates/details this approach

Comments

2

The int[] or int[][] is not a primitive data type. It is an Object in Java. And with an Object, the size cannot be calculated straight away.

5 Comments

where does +sizeof(int) come from?
A reference might not be 4 bytes depending on your platform.
@Matti: Agreed. The whole stuff is not correct. Let me edit it.
Writing the reference memory as sizeof(int) is misleading, even if on that particular platform it is 4 bytes.
I think if we keep on editing to make it technically correct we will settle with "there is no easy accurate way" :P
2

I know this is an old question, but I had the same one and the information given in this thread did not help me. The source that gave me the information I needed: https://www.javamex.com/tutorials/memory/array_memory_usage.shtml

Here is my case: I have a big array

int a[][] = new int[m][n];

where "big" is in fact misleading: m is big (3^18 = 387420489) but n is small (4). I kept running into memory problems that I did not understand, since m * n * 4 = 6198727824 (~6GB) whereas I have 16GB of RAM (and 12 allowed to the JVM with -Xmx12G). The link I just put gave me the answer:

each of the 10 rows has its own 12-byte object header, 4*10=40 bytes for the actual row of ints, and again, 4 bytes of padding to bring the total for that row to a multiple of 8

This is where the memory of my two-dimensional array substantially deviates from 4 * m * n: here, because n is small (4), the size of each row is really different from 4 * n; if you apply the formula given in the link (even if it is approximate), you get, for each row: 12 (header) + 4 * 4 (four ints) + 4 (padding to a multiple of 8 bytes) = 32. This is twice the cost I expected, and explains that I run into memory overflow.

Comments

2

Yann's answer above is correct, I double-checked it via a Heap dump.

Here's the data we need to compute the exact memory size of an array (source: https://www.javamex.com/tutorials/memory/array_memory_usage.shtml) :

  • Java selected type size (eg: double = 8 bytes) 'S'
  • Java array rounding up to multiple of: 8 bytes 'q'
  • Java reference size: 4 bytes 'R'
  • Java array header size: 12 bytes 'H'

Forumulas:

For a double[N] = (N * S + H) + (N * S + H) % q = 'x'

For a double[M][N] = [M * (x + R) + H] + [M * (x + R) + H] % q = 'y'

As an example:

double[10] = (10 * 8 + 12) + (10 * 8 + 12) % 8 = 96 Bytes

double[10][10] = [10 * (96 + 4) + 12] + [10 * (96 + 4) + 12] % 8 = 1016 Bytes

Simply multiplying the underlying primitive type (wrong) would have yield:

double[10] = 8 * 10 = 80 Bytes

double[10][10] = 8 * 10 * 10 = 800 Bytes

Comments

0

for original type:base type and size of Byte

  • boolean 1
  • byte 1
  • char 1
  • int 4
  • float 4
  • long 8
  • double 8
  • Interger 24 (16 for Class instance + 4 for int + 4 for memory alignment)

int a[M]: 24+4M

(16 for Class + 4 for save array size + 4 for memory alignment) + (for M size of double, we need 4 * M)

int a[M][N]: (24+4M) + M*(24+4N) = 24+28M+4MN ~~~4MN

treat a[M][N] as M size of double array a[N] plus one extra array to hold the reference of all M size array start point.

2 Comments

when you are discussing different types, we may have different size, but for int, we could have an calculation(there may some gap due to memory alignment)
M = ?, the array is always declared int... this answer could be improved.

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.