10

Javaプログラムで参照できるように、何百万ものX/Yダブルペアを保存する必要があります。オブジェクト参照の数だけでなく、メモリ消費量もできるだけ少なくしたいと思います。したがって、2つのポイントを小さな二重配列で保持することをお勧めすることを考えた後、セットアップは次のようになります。

double[] node = new double[2];
node[0] = x;
node[1] = y;

配列を使用すると、次のように、クラスとクラスで使用されるX変数およびY変数の間のリンクが妨げられると考えました。

class Node {
     public double x, y;
}

ただし、クラスのパブリックフィールドの格納方法を読んだ後、フィールドは実際にはポインタのような構造ではない可能性があることに気付きました。おそらく、JVMはこれらの値を連続したメモリに格納しているだけで、アドレスなしでそれらを見つける方法を知っています。私のポイントのクラス表現を配列よりも小さくします。

それで問題は、どちらがより小さなメモリフットプリントを持っているかということです。なぜ?

クラスフィールドがポインタを使用するかどうか、つまり32ビットのオーバーヘッドがあるかどうかに特に関心があります。

4

3 に答える 3

5

後者の方がフットプリントが小さくなります。

プリミティブ型は、包含クラスにインラインで格納されます。したがって、Node1つのオブジェクトヘッダーと2つの64ビットスロットが必要です。指定する配列は、1つの配列ヘッダー(> =オブジェクトヘッダー)と2つの64ビットスロットを使用します。

この方法で100個の変数を割り当てる場合は、ヘッダーサイズが異なるだけなので、それほど重要ではありません。

警告:JVMを指定しなかったため、これはすべて推測に基づくものです。これらの詳細の一部は、JVMによって異なる場合があります。

于 2012-09-03T23:23:19.607 に答える
0

まず、実際のスペース使用量は、使用している JVM によって異なることを述べておく必要があります。これは厳密に実装固有です。以下は、典型的な主流の JVM です。

問題は、どちらがメモリ フットプリントが小さいかということです。なぜ?

2 番目のバージョンは小さいです。配列には、配列の長さを保持するオブジェクト ヘッダーの 32 ビット フィールドのオーバーヘッドがあります。非配列オブジェクトの場合、サイズはクラス内で暗黙的であり、個別に表す必要はありません。

ただし、これは配列オブジェクトごとの固定オーバーヘッドであることに注意してください。配列が大きくなればなるほど、オーバーヘッドは実際には重要ではなくなります。また、配列ではなくクラスを使用することの裏返しとして、インデックスが機能せず、結果としてコードがより複雑 (かつ遅く) になる可能性があります。

Java 2D 配列は、実際には 1D 配列 (など) の配列であるため、同じ分析をより高い次元の配列に適用できます。配列の任意の次元のサイズが大きいほど、オーバーヘッドの影響は少なくなります。配列のオーバーヘッドは、2x10配列よりも少なくなり10x2ます。(考えてみてください... 長さ 2 + 2 の長さ 10の配列1 つと、長さ 10 + 10 の長さ 2 の配列 1 つ。オーバーヘッドは配列の数に比例します。)

私は特に、クラス フィールドがポインターを使用するかどうか、つまり 32 ビットのオーバーヘッドがあるかどうかに関心があります。

(実際には、クラス フィールドではなく、インスタンス フィールドについて話している。これらのフィールドはstatic... ではない)

型がプリミティブ型のフィールドは、参照なしでオブジェクトのヒープ ノードに直接格納されます。この場合、ポインターのオーバーヘッドはありません。

ただし、フィールド タイプがラッパー タイプである場合 (例:Doubleではなくdouble)、参照のオーバーヘッドと、オブジェクトのオブジェクト ヘッダーのオーバーヘッドが発生する可能性がありDoubleます。

于 2012-09-04T00:46:28.117 に答える
0

あなたの最大の問題はデータを保存することではなく、データを取得し、インデックスを作成し、操作することだと思います。

ただし、基本的には、配列が最適です。ポインターを節約したい場合は、1 次元配列を使用してください。(誰かがすでにそう言っています)。

于 2012-09-03T23:39:34.413 に答える