
こんにちは.
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になっていました.
分かりづらい文章で大変申し訳ありませんでした.
何かアドバイスいただければありがたいです.
No.1ベストアンサー
- 回答日時:
動的に確保したメモリを同時にアクティブに出来る合計サイズは、物理メモリ量を超える事は出来ません。
「メモリをアクティブにする」とは「CPUが物理的にアクセスが可能なメモリに対して、確保した領域をマッピングする」と言う事です。つまり「CPUが何時でも直接メモリにアクセス出来るようにする」と言う事です。
物理メモリが768MBしか無いのに「CPUが物理アクセス可能な領域を1024MB(1GB)作れ」と言っても無理な訳です。
「仮想メモリがあるから」と安心は出来ない訳です。
仮想メモリが使われるのは「プロセスをスイッチングする際、今まで動いていたプロセスをサスペンドし、サスペンドされるプロセスが確保していた動的メモリの物理メモリ内容を仮想メモリに移動し、他のプロセス用に物理メモリを開け渡す時」と「巨大な動的メモリを確保した際、アクティブではないメモリページを仮想メモリに保存する時」です。
仮想メモリを有効に使いたい場合は、API関数でメモリハンドルを作成し、物理メモリサイズを超えない大きさのアクティブページを作り、そこに対してメモリの読み書きを行い、読み書きが終わったアクティブページを非アクティブにして仮想メモリに追い出す、と言う処理が必要です。
メモリ使用量を半分にしたプログラムを2つ実行してエラーにならないのは「ある一瞬だけに注目した場合、物理メモリ上には、プログラム1つ分のメモリしか居ない」からです。
教えていただき,どうもありがとうございました.
確かに,タスクマネージャでメモリの消費量を追っていくと,物理メモリを超えるくらいでエラーになっていました.
今後とも質問させていただくことがあるかと思いますが,どうぞよろしくお願いいたします.
No.2
- 回答日時:
サーバー系で無いWindowsだと使える論理メモリ上限は4GBで、うち2GBはOS領域のため、通常のプロセスが使えるのは2GBまでです。
(OSの制限)この2GBも全てヒープとして使えるわけではなく、プログラム自身の領域、スタック領域にも使われますし、ライブラリだのDLLだのが消費するでしょうから、更に少なくなります。
もしかすると、使っているライブラリや何かで更に制限があるかも知れません。
プログラムを二つ実行する場合はそれぞれ独立したメモリ空間が使えますから、同時に使えるメモリ容量は2GBを超えることが可能ですから、
症状から考えて単純に消費メモリが大きすぎて実行不可能の状態だろうと思われます。
仮想メモリのサイズは関係ありません。
これは動作している全てのプロセスが使うメモリの合計の上限が変わるだけです。
#1の方が書かれている内容は、newで確保した領域の場合は関係ないと思います。
物理メモリをロックして使うような話なら別ですが。
プログラムからメモリを確保しようとした場合,仮想メモリのサイズは関係ないのですね.
結局のところ,もっとも簡単に問題を解決するのはメモリ増設であるようです.
貴重なご意見本当にありがとうございました.
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルVBA 大容量CSVファイル...
-
メモリが不足しています(VBA)
-
C言語初心者です。debug assert...
-
EXCEL-VBAにてADOのレコードセ...
-
ファイルマッピング関数で失敗
-
DirectX9でのテクスチャフォー...
-
エクセルのメモリ使用状況/Appl...
-
ちなみに、for (i = 0; str[i] ...
-
C言語で再帰的処理が出来ない理由
-
関数内でVirtualAllocで確保し...
-
ルネサスマイコン(R8C) ビルド...
-
H8 マイコン セクションの設...
-
VBAの配列サイズとメモリに関して
-
逆コンパイルと逆アセンブルの...
-
Macターミナルで実行中のプログ...
-
powershell を使いカレントディ...
-
バックグラウンドのプロセスの...
-
マイコンからプログラムを読み...
-
sendkeysにてALT+CTRL+INSERTを...
-
スレッドにて同一メモリの書き...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
メモリが不足しています(VBA)
-
VBAの配列サイズとメモリに関して
-
C言語で、メモリを解放しないで...
-
エクセルVBA 大容量CSVファイル...
-
メモリのセグメント違反の解決...
-
エクセルのメモリ使用状況/Appl...
-
「ヒープサイズの設定」て何?
-
【C言語】再帰が時間がかかる...
-
バッチファイルでの実行EXEのメ...
-
ReadEventLogについて
-
メモリを解放しないとどうなる?
-
LoadLibraryしたらFreeLibrary
-
C言語における再帰呼び出しの...
-
EXCEL-VBAにてADOのレコードセ...
-
メモリ不足
-
クリスタルレポートでメモリ不...
-
Bitmapを重ね合わせる方法
-
これて逆じゃないですか?
-
ルネサスマイコン(R8C) ビルド...
-
closeとメモリの開放について
おすすめ情報