- ベストアンサー
動的確保できるメモリ容量
こんにちは. 2個のファイルを同時に開いて処理するプログラムを作成したところ, メモリの確保に失敗するエラー(std::bad_alloc)が発生してしまいます. *********************** 環境 OS:WindowsXP-sp2 メモリ:768 MB HD空き:約30GB 開発環境:C++Builder 6 *********************** 開こうとするファイルは,各250MB程度で,それぞれを読み込んだ後,それ ぞれに対して同じ大きさの配列を確保するため,必要メモリ容量は, 約 1GB 程度になります. ちなみに,配列の確保はnewを用いています. PCに搭載している物理メモリが768MBなので,仮想メモリにアクセスする のは当然だと思います.ただ,ハードディスクの空きも十分なので,実行 速度が遅くなったとしても,無事処理できると思っていました. ヒープサイズが関係していると思い,C++Builderのリンカの設定で予約ヒー プサイズを最大に設定しましたがダメでした. また,Windowsのシステムのプロパティで,仮想メモリを4000MBにしました がこれもダメでした. プログラムで一度に確保できるメモリサイズには限界があり,それ以上の サイズを確保することは不可能なのでしょうか? なお,2つのファイルを同時に開いて処理しようとするとエラーになって しまいますが,作成したソフトを2つ実行して,それぞれで上記ファイルを 1つずつ開くと,合計の必要メモリは同じにもかかわらず,エラーになりま せん. このときタスクマネージャでPF使用量を確認すると,1.2GBになっていました. 分かりづらい文章で大変申し訳ありませんでした. 何かアドバイスいただければありがたいです.
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
動的に確保したメモリを同時にアクティブに出来る合計サイズは、物理メモリ量を超える事は出来ません。 「メモリをアクティブにする」とは「CPUが物理的にアクセスが可能なメモリに対して、確保した領域をマッピングする」と言う事です。つまり「CPUが何時でも直接メモリにアクセス出来るようにする」と言う事です。 物理メモリが768MBしか無いのに「CPUが物理アクセス可能な領域を1024MB(1GB)作れ」と言っても無理な訳です。 「仮想メモリがあるから」と安心は出来ない訳です。 仮想メモリが使われるのは「プロセスをスイッチングする際、今まで動いていたプロセスをサスペンドし、サスペンドされるプロセスが確保していた動的メモリの物理メモリ内容を仮想メモリに移動し、他のプロセス用に物理メモリを開け渡す時」と「巨大な動的メモリを確保した際、アクティブではないメモリページを仮想メモリに保存する時」です。 仮想メモリを有効に使いたい場合は、API関数でメモリハンドルを作成し、物理メモリサイズを超えない大きさのアクティブページを作り、そこに対してメモリの読み書きを行い、読み書きが終わったアクティブページを非アクティブにして仮想メモリに追い出す、と言う処理が必要です。 メモリ使用量を半分にしたプログラムを2つ実行してエラーにならないのは「ある一瞬だけに注目した場合、物理メモリ上には、プログラム1つ分のメモリしか居ない」からです。
その他の回答 (1)
- terra5
- ベストアンサー率34% (574/1662)
サーバー系で無いWindowsだと使える論理メモリ上限は4GBで、うち2GBはOS領域のため、通常のプロセスが使えるのは2GBまでです。(OSの制限) この2GBも全てヒープとして使えるわけではなく、プログラム自身の領域、スタック領域にも使われますし、ライブラリだのDLLだのが消費するでしょうから、更に少なくなります。 もしかすると、使っているライブラリや何かで更に制限があるかも知れません。 プログラムを二つ実行する場合はそれぞれ独立したメモリ空間が使えますから、同時に使えるメモリ容量は2GBを超えることが可能ですから、 症状から考えて単純に消費メモリが大きすぎて実行不可能の状態だろうと思われます。 仮想メモリのサイズは関係ありません。 これは動作している全てのプロセスが使うメモリの合計の上限が変わるだけです。 #1の方が書かれている内容は、newで確保した領域の場合は関係ないと思います。 物理メモリをロックして使うような話なら別ですが。
お礼
プログラムからメモリを確保しようとした場合,仮想メモリのサイズは関係ないのですね. 結局のところ,もっとも簡単に問題を解決するのはメモリ増設であるようです. 貴重なご意見本当にありがとうございました.
お礼
教えていただき,どうもありがとうございました. 確かに,タスクマネージャでメモリの消費量を追っていくと,物理メモリを超えるくらいでエラーになっていました. 今後とも質問させていただくことがあるかと思いますが,どうぞよろしくお願いいたします.