2

OK、残念ながら作業を完了するために巨大なデータ構造を使用する必要があるプログラムを書いていますが、初期化中に「メモリ不足エラー」で失敗しています。それが何を意味し、なぜそれが問題なのかは完全に理解していますが、プログラムでこの大きな構造を使用する必要があり、それを保存する他の方法がわからないため、それを克服するのに苦労しています。

このプログラムはまず、私が提供する大量のテキスト ファイルのコーパスにインデックスを付けます。これはうまくいきます。

次に、このインデックスを使用して、大きな 2D 配列を初期化します。この配列には n² のエントリが含まれます。ここで、"n" はテキスト コーパス内の一意の単語の数です。私がテストしている比較的小さなチャンク (約 60 ファイル) では、約 30,000x30,000 のエントリを作成する必要があります。意図した完全なコーパスでも実行すると、これはおそらく大きくなります。

インデックス作成後、データ構造を初期化している間(後で作業します)、毎回一貫して失敗します。

私が行ったことは次のとおりです。

  • int[]の代わりにプリミティブを使用するようにコードを修正します。TreeMap
  • 冗長な構造などを排除する...
  • また、-Xmx2g割り当てられたメモリを最大化するためにプログラムを実行しました

これは単純なコード行のソリューションではなく、非常に新しいアプローチが必要になる可能性が高いと確信しています。私はそのアプローチが何であるかを探しています、何かアイデアはありますか?

ありがとう、B.

4

4 に答える 4

2

ほとんどのエントリは0になるようです(配列を何に使用しているかについていくつかの仮定を立てます)。そうであれば、スパース行列表現の使用を検討することをお勧めします。

本当に多くのエントリがある場合(オーバーヘッドがないと仮定しても、現在の配列はすでに3ギガバイトを超えています)、何らかのオンディスクストレージ、または遅延ロード/アンロードシステムを使用する必要があります。

于 2010-03-17T05:02:26.423 に答える
2

メモリ不足の問題にはいくつかの原因があります。

まず、最も単純なケースは、単により多くのヒープが必要な場合です。プログラムが2Gで正しく動作できる場合は、最大512Mのヒープを使用しています。増加は-Xmx2048mJVMオプションとして使用でき、問題ありません。また、64ビットVMは、そのデータの構成に応じて、32ビットVMの最大2倍のメモリを使用することに注意してください。

問題がそれほど単純でない場合は、最適化を検討できます。オブジェクトをプリミティブなどに置き換える。これはオプションかもしれません。あなたが投稿した内容に基づいて、私は本当に言うことはできません。

ただし、最終的には、仮想化分割のどちらかを選択する必要がある交差点に到達します。

このコンテキストでの仮想化とは、単に、ある形式よりも多くのメモリがあるふりをすることを意味します。オペレーティングシステムは、これを仮想アドレススペースで使用し、ハードディスクスペースを追加メモリとして使用します。これは、一度に一部のデータ構造のみをメモリに保持し、残りをセカンダリストレージ(ファイルやデータベースなど)に保持することを意味する場合があります。

パーティショニングとは、データを複数のサーバー(実サーバーまたは仮想サーバー)に分割することです。たとえば、NASDAQで株式取引を追跡している場合は、server1に「A」、server2に「B」などで始まる銘柄コードを配置できます。データをスライスして削減するための合理的なアプローチを見つける必要があります。または、相互通信がスケーラビリティを制限するため、相互通信の必要性を排除します。

非常に単純なケースです。保存しているのが30Kの単語と30Kx30Kの単語の組み合わせである場合、4つのサーバーに分割できます。

  • AM x AM
  • AM x NZ
  • NZ x AM
  • NZ x NZ

それはただ一つの考えです。繰り返しになりますが、詳細を知らずにそれを行うのは難しいです。

于 2010-03-17T05:06:11.327 に答える
1

これは、大規模なデータセットを扱う際の一般的な問題です。必要なだけ最適化できますが、メモリは(おそらく)十分ではなく、データセットがもう少し大きくなるとすぐに、まだ煙が出ています。最もスケーラブルなソリューションは、メモリ内の保持を減らし、チャンクで作業し、構造をディスク(データベース/ファイル)に永続化することです。

于 2010-03-17T05:04:05.943 に答える
0

2D配列の値ごとに完全な32ビット(整数のサイズ)が必要ない場合は、バイトなどの小さい型でうまくいくでしょうか。また、可能な限り多くのヒープスペースを与える必要があります。2GBは、最新のシステムではまだ比較的小さいです。RAMは、特にメモリ内で多くの処理を行うことを期待している場合は安価です。

于 2010-03-17T05:00:53.407 に答える