3

Javaで複数の(数百万の)小さなオブジェクト(3から6のDouble、おそらく文字列を含む)にメモリを割り当てる最良の方法(最小のメモリ消費/スワッピング)は何ですか?

3 つの異なる戦略を考えることができます。

  1. ナイーブ:特別なことは何もせず、仮想マシンにメモリを処理させます。

  2. ファクトリ スタイル:ファクトリ クラスを介してオブジェクトを作成します。Factory は一度に複数のオブジェクトを作成し (バッチごとに数千程度)、オブジェクトのリサイクルを処理します (使用済みのオブジェクトが利用可能な場合、新しいオブジェクトを作成する必要はありません)。

  3. 配列スタイル:データを基本的な配列に格納します。インデックス番号を介してデータにアクセスします。

明確化: ターゲット プラットフォームのメモリが非常に少ない (512 メガバイト)。

4

3 に答える 3

1

もちろん、オプション 3 が最もメモリ効率が高くなります。

例:

class Point {
  double x;
  double y;
}

Point オブジェクトには 12、x と y には 2 * 8 が必要 = 28 バイト
Point[]: Point オブジェクトの配列を使用: ポイントごとに 28 バイト (および配列自体には 16 バイト)

順序
int[] xycoords: x1,y1,x2,y2,.....xn,yn:

x、y 座標ごとに 16 バイトが必要です。これは、クラス ポイントと比較して 57% です。

ナビゲーション システムを構築しており、データ表現が最適ではないため、ヨーロッパの半分しか保存できないとします。

ただし、
オプション 3 はメモリを節約しますが、最初のバージョンではオブジェクト アプローチを使用することをお勧めします。配列アプローチでは、特に複雑なアルゴリズムの場合、コーディング エラーの可能性がはるかに高くなります。

バージョン 1 が機能したら (ユニット テストがあることを願っています)、配列アプローチを使用して v2 を実装できます。すべてがまだ機能していることを単体テストで確認してください。

于 2013-07-16T13:24:48.453 に答える
1

最悪の場合 (6 Double) を想定すると、すべてがメモリに収まるはずです。

説明: あなたはダブルと言い、ダブルではありません。私の記憶が正しければ、ラッパーのオーバーヘッドは 16 バイトです。これは、16 (ラッパーのオーバーヘッド) + 8 (double 値) = Double あたり 24 バイトを意味します。6 倍の場合 200 万 : ~ 274 Mo

結果: オプション 1 に進みます。

いくつかの最適化のヒントが必要な場合:

  • ダブルではなくダブルを選びましょう。
  • オーバーヘッドのために基本的な配列を使用せずに、代わりに Java の BitSet か、より優れた (オーバーヘッドが少ないと思います) Colt のようなBitVectorを使用したライブラリを試してください。これは、パフォーマンスを犠牲にすることなく、スペースを最適化するのに役立ちます。
  • 考えたことは何でも試してみてください。ただし、ベンチマークを行ってください。期待どおりに機能しない場合でも、経験から学ぶことができます。
于 2013-07-16T14:02:32.103 に答える