2

データベースから大量のデータが取得されるため、C++ アプリケーションがメモリ不足になることがあります。32 ビットの WinXP マシンで実行する必要があります。

透過的に (ほとんどの既存のコードで) データ オブジェクトをディスクにスワップ アウトし、オンデマンドでのみメモリに読み込むことができるので、32 ビット Windows がプロセスに与える2GB に制限されませんか?

VirtualAllocAddress Window Extensionsを見てきましたが、それが私が望むものかどうかわかりません。

また、質問者がファイルマッピングを作成し、そこにオブジェクトを作成したいというこのSOの質問も見つけました。1 つの答えplacement newは、コードの残りの部分に対してかなり透過的であるように聞こえるものを使用することを示唆しています。

これにより、アプリケーションが物理メモリを使い果たすのを防ぐことができますか? 結局のところ、32 ビットのアドレス空間の制限がまだあるため、完全にはわかりません。それとも、これは多くのオブジェクトを作成しようとしたときに発生する別の種類の問題ですか?

4

1 に答える 1

1

32 ビット オペレーティング システムを使用している限り、これについてできることは何もありません。実際にディスクにスワップアウトされているかどうかに関係なく、仮想メモリに 3GB (Windows の場合は 2GB) を超えるデータを保持する方法はありません。

歴史的に、データベースは常に、読み取り、書き込み、およびシークを使用してこの問題を処理してきました。そのため、メモリから直接データにアクセスするのではなく、偽の (64 ビット) ポインターを使用します。データはブロック (通常は約 4kb) に分割され、これらのブロックの数がメモリに割り当てられます。偽のポインターアドレスからデータにアクセスしたい場合、ブロックがメモリにロードされているかどうかを確認し、そこからアクセスします。そうでない場合は、空のスロットを見つけてコピーし、アドレスを返します。空きスロットがない場合、データの一部がディスクに書き戻され (変更されている場合)、そのスロットが再利用されます。

これの本当の利点は、システムに十分な RAM がある場合、オペレーティング システムはいつでも 2GB をはるかに超えるこのデータを RAM にキャッシュし、ディスクから実際に読み書きしているように感じると、オペレーティング システムはおそらくメモリ内でデータをコピーしているだけでしょう。もちろん、これには 3 GB を超える物理メモリをサポートする 32 ビット オペレーティング システム (PAE を使用する Linux や Windows Server など) が必要です。

SQLite には、 this の優れた自己完結型の実装があり、おそらくほとんど手間をかけずに利用できます。

これを行いたくない場合、唯一の選択肢は、64 ビット オペレーティング システムを使用するか、任意の時点でより少ないデータで作業することです。

于 2012-08-23T12:45:25.047 に答える