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?

asked Jun 4, 2010 at 8:37
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.

answered Feb 17, 2013 at 10:05
2
  • Where do you get the 24 byte overhead from? I assume the number is for some specific VM. Commented Jul 19, 2013 at 11:01
  • 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. Commented Aug 12, 2014 at 15:52
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.

answered Jun 4, 2010 at 8:41
5
  • 2
    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. Commented Jun 4, 2010 at 8:44
  • how is represented in memory a multidimensional array? Commented Jun 4, 2010 at 8:47
  • I deleted my answer since I know of no way to calculate the exact size inclusive of overhead. Commented Jun 4, 2010 at 8:48
  • 5
    @xdevel2000: Java does not have multidimensional arrays. Only arrays of arrays. Commented Jun 4, 2010 at 8:51
  • 1
    @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. Commented Jun 4, 2010 at 9:56
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

answered Jun 4, 2010 at 9:04
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.

answered Jun 4, 2010 at 8:38
5
  • where does +sizeof(int) come from? Commented Jun 4, 2010 at 8:42
  • A reference might not be 4 bytes depending on your platform. Commented Jun 4, 2010 at 8:48
  • @Matti: Agreed. The whole stuff is not correct. Let me edit it. Commented Jun 4, 2010 at 8:49
  • Writing the reference memory as sizeof(int) is misleading, even if on that particular platform it is 4 bytes. Commented Jun 4, 2010 at 8:50
  • I think if we keep on editing to make it technically correct we will settle with "there is no easy accurate way" :P Commented Jun 4, 2010 at 8:52
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.

answered Jun 5, 2020 at 8:25
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

answered Jan 8, 2021 at 10:17
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.

answered Feb 22, 2017 at 14:27
2
  • 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) Commented Feb 22, 2017 at 14:35
  • M = ?, the array is always declared int... this answer could be improved. Commented Jul 26, 2017 at 2:39

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.