Harmony JVM のオブジェクト レイアウトを確認します (JVM の他の実装も同様だと思います)。Java の各オブジェクトには、JVM の重要な情報を含むオブジェクト ヘッダーがあります。最も重要なのは、オブジェクトのクラス ( 1 語) への参照です。さらに、GC によって使用され、同期を管理するために使用されるフラグがいくつかあります。つまり、ロックワード (すべてのオブジェクトを同期できるため) が別の1 ワードを占めます(部分的なワードを使用するとパフォーマンスが低下します)。これは 2 ワードで、32 ビット システムでは 8 バイト、64 ビット システムでは 16 バイトです。配列にはさらに、配列の長さの int フィールドが必要です。これはさらに4 バイト、場合によっては8 バイトです。64 ビット システムで。したがって、配列ごとに、32 ビット マシンでは 12 バイトが追加され、64 ビット マシンでは 24 バイトになる場合があります。
プログラムには、6 つの配列の配列があります。100480507 1D 配列。したがって、追加のメモリ消費量は約 1.2 + 0.6 GB であり、これは連続メモリの非常に大きなブロックです。オーバーヘッドは約 200% です。
コードを次のように変更すると:
public class MemTest {
public static void main(String[] args) {
int NUM_RECORDS = 100480507;
byte[] completeArray = new byte[NUM_RECORDS * 6];
System.out.println("Array created");
}
}
作成する配列は 1 つだけなので、オーバーヘッドは非常に小さくなります。合計で約0.6GB。
コードが次のように変更されたとき:
public class MemTest {
public static void main(String[] args) {
int NUM_RECORDS = 100480507;
byte[][] completeArray = new byte[NUM_RECORDS][6];
System.out.println("Array created");
}
}
全部で 7 つの配列を取得しました。プログラムはすぐに終了します。
コード スタイルで別の 0.6GB メモリを作成しますが、要素の型を int から long に変更します。
public class MemTest {
public static void main(String[] args) {
int NUM_RECORDS = 12560063;
long[][] completeArray = new long[NUM_RECORDS][6];
System.out.println("Array created");
}
}
プログラムはすぐに終了することもできます。オーバーヘッドは約 150M/600M = 25% です。