再割り当てが必要なベクターに連続したメモリを使用できないためにクラッシュしたプログラムをデバッグしています。では、仮想メモリが使用されない理由について質問があります。仮想メモリはどのように使用できますか? ありがとう。
3 に答える
仮想メモリは OS によって自動的に使用されます。これを気にする必要はありません。
あなたの場合、32 ビット アプリケーションを実行する可能性が最も高いでしょう。Windows の 32 ビット プロセスのユーザー アドレス空間は 2 GB に制限されています (Windows が特定のキーで起動されている場合は 3 GB です)。ベクトルが数百メガバイトを超える連続したアドレス空間を必要とする場合、(アドレス空間の断片化が原因で) 問題になる可能性があります。
もちろん、どのプロセスでもメモリ不足になる可能性があります (仮想メモリやスワップ ファイルなどを使用している場合でも)。タスク マネージャーでプログラムのメモリ使用量を確認します。
仮想メモリは、最新の OS (Linux、Unix、Windows、MacOS、Symbian など) で実行されるプログラムとして得られる唯一のメモリです。
あなたの問題は、ベクトルに十分な大きさの連続した仮想アドレス範囲が1つも存在しないことだと思われます[1]。たとえば、32 ビット プロセスでは 1.5 GB 以上が必要で、一度に 2 GB しか使用できないため、どちらの側にも他のビットを詰め込むための「余地」があまりないのではないかと思います。 "middle" は 1.5GB 未満です。特に、ベクトルが拡大している場合は、ベクトルの 2 つのコピーが必要になります。1 つは現在のサイズで、もう 1 つはコピー先の 2 倍のサイズです。
ベクトルがどれくらいの大きさである必要があるかを知っていると仮定すると、単純な解決策は、そのサイズを設定することです。vector<int> vec(some_size);
わからない場合は、さらにいくつかの解決策があります。
64 ビット OS を使用している場合はLARGEADDRESSAWARE
、実行可能ファイルのフラグを設定してみてください (Windows であると仮定します)。64ビットOSはOS自体(32ビットアドレス範囲外に十分に存在する)のために大量のメモリスペースを予約する必要がないため、これによりかなり多くのメモリが得られるはずです.32ビットOSでは/3GB で OS を起動し、上記のフラグを設定する必要があります。
または、コードを 64 ビットとしてコンパイルします (必要に応じて 64 ビット OS にアップグレードした後)。
[1] もちろん、ドライバーを作成し、DMA に使用するバッファーとして何メガバイトもの物理メモリを割り当てようとしている場合を除きますが、そう言ったはずです。
この問題は、メモリや仮想メモリとは関係ありません。配列には、連続した範囲のアドレスが必要です。アドレス空間 (通常、Win32 プログラムでは 2 GB) は断片化されているため、使用可能な十分なスペースがありません。
アドレスを取得できれば、Windows はそれらに対応する仮想メモリを自動的に提供します。
アプリを 64 ビットに移行するときが来ました。