开发者

how calculate java array memory usage

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?


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.


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.


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


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.


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.


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.


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜