教えてgooの識者のお知恵をお借りしたくご質問させていただきます。
表記の通り、C&C++を用いて、大容量のメモリ確保をスワップ無しで行いたく考えております。
質問の内容としてましては、(1)、(2)の2点があります。
(1) 「VirtualAllocに失敗するという理由としてどのような原因があるのでしょうか?」
VirtualAlloc関数に、引数MEM_RESERVE、MEM_COMMITを渡してメモリ確保を行ってみたのですが、
メモリ確保に成功するPCと成功しないPCが存在し、理由が分からずにいます。
(いずれもタスクマネージャなどで確認すると物理メモリの空き容量は1.3GB程度空いているPCです。)
(確保に失敗するPCで確認してみたところ、650MB付近までは確保に成功します。)
(2) 「VirtualAlloc以外にスワップを回避して大容量のメモリを確保する方法はあるのでしょうか?」
newでは確保ができるのですが(当然なのかもしれませんが)、
ページングファイルに移動されてしまうと処理が重たくなってしまうので採用できない方法だと考えています。
プログラムの内容は、外部インターフェースからの入力を待つために常駐し、入力した900MB分のデータを高速に処理するというものです。
900MBのデータ量は必須で、高速かつ安価なPC構成とする必要があるために全ての処理をメモリ上で行う方法を選択しました。
ハードウェアは2GB以上のメモリを搭載、Windows XP SP3 32bitのPCに限定しています。
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
当方も最近、本題と似たような実験を行っており、質問(1)に関連した回答をさせていただきます。
(※質問(2)についてはすぐには思い当たらないため割愛いたします。)
GUIを用いるプログラムであるのならば、GUIをロードする前にメモリを確保するというのは如何でしょうか?
当方が使用しているのはC++/CLI開発環境で作る単純なGUIアプリケーションで、起動時にメイン関数を
呼んでからGUIを起動する処理と同時にメモリ1GBを確保します。
また、実験に使用したPCのスペックは3台でいずれも、メモリ:2GB、OS:Windows XP SP3です。
物理メモリの空き容量が十分にある(2GB中1.5GB)にもかかわらず、質問者がおっしゃるように
使用するPCによりメモリ確保に成功するものと失敗するものとがあるのを確認したことがあります。
そこで何故なのかを原因を探っていたところ、以下の様な違いがあることが分かりました。
(1)GUIをロード中(もしくはその後)にメモリを確保する場合:
→失敗するPCの場合、約700MBまでしか確保できない。
(※PCにより異なると思われる。当方が確認できたのは1台のみ。)
(2)メモリ確保をGUIロードの直前までに実行する場合:
→メモリ確保に成功していたPCのみならず、今までに失敗していたPCでも成功。
前の回答者が述べられたとおり、成功するには確保するだけの連続したアドレス空間の空きが必要です。PCによりGUIロード時にポイントされるアドレスが同じであるとは限らず、その差異によるアドレス空間の分断がメモリ確保の成功・失敗を決めていたのではないかと考えています。
また、(2)のプログラムでVirtualAllocによるメモリ確保が最大でどれ位まで可能かも複数のPCで実験してみました。
その結果、(1)のプログラムでメモリ確保に成功のPCも失敗のPCも同じサイズ(約1.164GB)であることが分かりました。
2GB以上のメモリ搭載で32bit-OSのPCで、約900MBのメモリ確保をスワップ無しで実行できるようにするのであれば、プログラムの処理順序を変更することで本題の問題が回避できるのではないかと考えます。
貴重な実験結果のご報告有難うございます。とても有用な手法だと思います。
GUIのロードを行う順番による解決は思い至りませんでした。
参考にさせていただき実装方法を検討してみたいと思います。
私の方でもVirtualAllocによる最大確保可能な連続仮想アドレス容量がどの程度あるか、以下の3条件で実験してみました。
いずれもVisualStudio2008で空のプロジェクトを作成した後、main関数に入った直後にVirtualAllocで連続確保可能な容量を調べるようコードを追加しています。
PCのスペックは「メモリ:2GB、OS:WindowsXP SP3 32Bit」、
メモリの大量確保に失敗するPC1台です。結果、以下の通りとなりました。
(拙い知識での実験で問題点も多いかと思いますがご容赦ください。)
(1)Win32コンソールアプリケーション:1920MB
(2)CLRコンソールアプリケーション(.NET Freamwork 3.5):1403MB
(3)Windowsフォームアプリケーション(.NET Freamwork 3.5):767MB
上記結果からも推測するに、
evaWK0様にご教示頂いた通りの現象が起きている蓋然性が高いと私も考えます。
ご回答有難う御座いました。
No.1
- 回答日時:
まず、VirtualAllocは仮想アドレス空間を確保するだけでスワップアウト禁止にはしてくれません。
スワップアウトを禁止するにはVirtualLockを併用する必要がありますが、これでロックできるメモリ量は標準では非常に小さいので、ワーキングセットを拡大する設定を行う必要があります。ただし、過大なメモリをスワップアウト禁止にするとシステムが不安定になる可能性があるのでお奨めしません。
(1)
上に書いたようにVirtualAllocは仮想アドレス空間を確保します。成功するには確保するだけの連続したアドレス空間の空きが必要です。32bitアプリケーションのユーザーアドレス空間2GBに対して900MBはけっこう大きいので、先に呼んだVirtualAllocやリンクされたDLLなどでアドレス空間が分断されると確保に失敗する可能性が生じます。
実行するPCによって結果が異なるということだと標準ライブラリDLLのバージョン違いでリンクアドレスかサイズが異なっているという可能性が考えられます。
(2)
プログラムでメモリ空間をスワップアウト禁止するには最初に書いたようにVirtualLockがあります。
他の手法としては、
1.ページファイルサイズを0にしてスワップアウト先を無くす。
2.十分なメモリを用意してスワップアウトされないことに賭ける。
くらいが思いつくところです。
詳細なご回答有難うございます。
スアップアウウト禁止にVirtualLockを併用しなければならない点、ご指摘の通りでした。
プログラムを見直したところ、事前にVirtualAllocで予約、使用する際にはVirturalLockを使用するといった方法をとっています。
(1)のご回答について
ご指摘の通りドライバ関係で呼んでいるDLL上等にVirtualAllocやVirtualLockが使われている可能性があるかもしれません。
また、SDKのバージョンなどはなるべく揃えていますが、リンクアドレスやサイズが変わってしまうという可能性には気づきませんでした。
(2)のご回答について
やはり具体的手法としてはVirtualLockが最も現実的ですね。
環境に依存せず確実に確保できるタイミングを探してみようかと思います。
環境によってプロセスのメモリ使用状況がどう異なるのか、仮想アドレスの予約状況をVirtualQueryを利用して、ログで出力するようなクラスを作成し、ところどころメモリの使用状況をチェックしてみようかと思います。
また、C&C++という前提でしたが、CLIも組み込まれているようなので、その点がメモリ管理に影響している可能性があると踏んでいます(質問の前提条件に挙がってない事実でした。すみません。。。)
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Windows 8 カスペルスキー削除後の外付HDD不具合 3 2023/03/06 06:41
- CPU・メモリ・マザーボード メモリが使用可能にならない 3 2022/08/13 17:13
- ドライブ・ストレージ 最近は従来のUSBメモリと同じ様な外観のSSDが出てますよね。 これってPC等のバックアップ用に使え 8 2023/01/05 12:45
- Android(アンドロイド) dミュージックについて 1 2022/06/06 18:50
- ノートパソコン このノートパソコンで大丈夫でしょうか? 2 2023/04/22 21:01
- 宇宙科学・天文学・天気 AIが答えた方程式 1 2023/02/20 00:12
- BTOパソコン PCの選び方 6 2022/09/11 00:16
- CPU・メモリ・マザーボード Windows10 64bitパソコンのメモリ 4GBから8GBへ増設 11 2023/01/25 18:20
- USBメモリー・SDカード・フラッシュメモリー PCの動画写真を保存する方法教えて 素人で申し訳ありませんが 昔USBメモリを使って保存してましたが 6 2023/07/21 22:01
- デスクトップパソコン studio diffusionを使うのに必要なPCメモリ 1 2022/11/23 22:40
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
大容量のメモリ確保をスワップ...
-
エクセルのメモリ使用状況/Appl...
-
Apacheでバーチャルホストの最...
-
変数をあなたの身近なものに例...
-
LoadLibraryしたらFreeLibrary
-
【C言語】再帰が時間がかかる...
-
ファイルマッピング関数で失敗
-
動的メモリとexit(C言語)
-
C言語で、メモリを解放しないで...
-
メモリのセグメント違反の解決...
-
closeとメモリの開放について
-
VBAの配列サイズとメモリに関して
-
C#におけるexeファイルのサイズ...
-
メモリが不足しています(VBA)
-
プログラム開発勉強専門のPC...
-
64bit C#アプリ メモリをたくさ...
-
メモリを解放しないとどうなる?
-
Macターミナルで実行中のプログ...
-
緯度、経度の 10進法と 60進法...
-
家電製品の電力周波数を変える機械
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語で、メモリを解放しないで...
-
VBAの配列サイズとメモリに関して
-
「ヒープサイズの設定」て何?
-
エクセルのメモリ使用状況/Appl...
-
エクセルVBA 大容量CSVファイル...
-
EXCEL-VBAにてADOのレコードセ...
-
バッチファイルでの実行EXEのメ...
-
メモリ不足
-
メモリのセグメント違反の解決...
-
メモリが不足しています(VBA)
-
【C言語】再帰が時間がかかる...
-
ファイルマッピング関数で失敗
-
C言語:関数のメモリ上でのサイ...
-
メモリの解放の仕方
-
VC++におけるメモリ使用量について
-
メモリの消費量について
-
Bitmapを重ね合わせる方法
-
メモリを解放しないとどうなる?
-
C#のOutOfMemoryException発生...
-
メモリの解放について VB6 VBA
おすすめ情報