Java の多次元配列のメモリ使用量について調べてみた
Java の多次元配列のメモリ使用量について調べてみたので、ちょっとメモしておきます。
C 言語だと、例えば int i[N][M] な多次元配列のメモリ使用量は、int が 4 byte なので 4 * N * M と単純に計算できる。
■ ArraySize.c
#include <stdio.h> void main() { int i[20000][10]; int msize = sizeof(i); printf("%d\n", msize); }
■ 実行結果
[root@centos62 c]# ./ArraySize 800000
ただ、Java の多次元配列は C 言語とかのそれとは違うらしく、上記みたいな 2 次元配列の場合、「1 次元配列のフィールドに 1 次元配列がある」みたいな感じになるようです。
・Arrays (The Java Tutorials > Learning the Java Language > Language Basics)
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
In the Java programming language, a multidimensional array is an array whose components are themselves arrays. This is unlike arrays in C or Fortran.
以下のドキュメントで多次元配列がわかりやすく図示されてます。
・Arrays
http://www.oracle.com/technetwork/community/join/member-discounts/ocajavase7ch04-1840093.pdf
以下もわかりやすく説明されてます ( 要は 正確には Java に多次元配列はないと )。
・A Guide to Optimization of Java Programs (JavaWorld 2000/9)
http://www.shudo.net/article/200009-JavaWorld-optimization/#java_techniques
「1 次元配列のフィールドに 1 次元配列がある」ということなので、int i[N][M] の場合、メモリ使用量の計算は、([フィールドの配列のサイズ] * N + α) + ((4 * M + α) * N)になるはず。
で、[フィールドの配列のサイズ] や α については、以下の「Java 配列オブジェクトの分析」あたりに情報があります。
・Java コードから Java ヒープまで
http://www.ibm.com/developerworks/jp/java/library/j-codetoheap/
[フィールドの配列のサイズ] が 4 byte ( *1 )、α が 128 bit ( 16 byte ) という感じです。
( *1 ) 配列のフィールドのサイズについては「表 1」に情報あるけど、ここに "配列" の記載がない。まぁ、配列はオブジェクトの一種なので「オブジェクト・フィールド」の 32 bit ( 4 byte ) ということでしょうか。
以上踏まえると、Java で int i[20000][10] な多次元配列のメモリ使用量は以下になるはず。
(4 * 20000 + 16) + ((4 * 10 + 16) * 20000) = 1200016 byte
実際に確認すると、まぁなかなか誤差ある感じですが・・・それなりの値になってる ( と思うことにします )。
■ ArraySize.java
class ArraySize { public static void main(String[] args) { System.out.println(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()); int i[][] = new int[20000][10]; System.out.println(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()); } }
■ 実行結果
[root@centos62 c]# java ArraySize 477312 1643280
※ 1643280 - 477312 = 1165968 byte ( 結構デカイ誤差やな・・・ )
ちょっと最後の検証結果が残念な感じですが、少なくとも C 言語みたいに単純に 4 * N * M みたいにはならないことはわかったというところで、以上とします。