締切り済みの質問
GlobalAlloc について
質問させて下さい。
VC++ 2005 MFC で開発しております。
仕様の概要と致しまして、
::GlobalAlloc()でHGLOBALを取得し、
メンバ変数に格納(Arrayでリサイクルしていくイメージ)した後、スレッドを走らせ格納したHGLOBALを
使い処理をした後に、GlobalFree()でメモリを開放します。
アプリの仕様上、スレッドの処理に少々時間がかかり
GlobalAlloc()とGlobalFree()が必ずしも一対一で実行されず、
スレッドのGlobalFree()が実行される前に別のGlobalAlloc()がくることがあります。
このような場合、下記のように確保するヒープ領域の取得したアドレスが
少しずつ増えてしまい、最終的には取得できなく(GlobalLockでNULLポインタ)なってしまいます。(4GB越え)
8バイトずつアドレスが増えていくとして
-------------------------------------------------
・一対一の場合
(同じアドレスが使用できる)
確保開放
(1)0008(2)0008
(3)0008(4)0008
(5)0008
・一対一でない場合
(開放される前に確保するので新しいアドレスを使用してしまう)
確保開放
(1)0008(2)0008
(3)0008
(4)0016(5)0008((3)メモリ)
(6)0024
(7)0032
(8)0040(9)0016((4)メモリ)
(10)0024((6)メモリ)
(11)0032((7)メモリ)
(12)0048
:
:
:
-------------------------------------------------
GlobalFree()がもれているのではなく
メモリを確保したものは遅れはするものの必ず開放はしています。
このような場合、上記の「一対一でない場合」の
(6)で「0024」番地ではなく「0008」番地からメモリを確保することは出来ないのでしょうか?
確保と開放が一対一に統合されていればこのような問題はない(常に同じアドレスを使用できるため)のですが、
アプリの使用上、仕方ないと考えております。
説明が複雑になってしまい、わかりにくいとは思いますが、
お詳しい方がおられましたら、ご教授の程宜しくお願い致します。
投稿日時 - 2008-02-19 18:01:48
0人が「このQ&Aが役に立った」と投票しています
回答(3件中 1~3件目)
>このような場合、下記のように確保するヒープ領域の取得したアドレスが
>少しずつ増えてしまい、最終的には取得できなく(GlobalLockでNULLポインタ)なってしまいます。(4GB越え)
そんなはずはないと思います。マルチスレッドを使わない実験コードを書いて確かめてみてはどうでしょうか。
もちろん、単純に、確保、解放、確保、解放・・・とするのではなくて、
確保、確保、解放、確保、確保、解放、解放・・・・・
といった感じで。
あと、確保する単位が細かすぎるように思えます。もっと大きな単位で確保した場合は、どのような挙動になるでしょうか。
投稿日時 - 2008-02-20 10:13:07
★最も簡単な方法
>確保と開放が一対一に統合されていればこのような問題はない(常に同じアドレスを使用できるため)のですが、
>アプリの使用上、仕方ないと考えております。
スレッドで確保、解放はしないでメインのスレッドで最大のサイズを確保。
プログラム終了時などで解放すれば楽でしょう。
・あとスレッドで処理する場合は排他処理を行います。
メモリ確保、解放だけでなく1つの変数の参照、代入でも排他処理を行うのが常識。
次のリンクを読んでみましょう。
http://itpro.nikkeibp.co.jp/article/COLUMN/20070603/273403/→『第3回 マルチタスクに不可欠な同期の仕組みを学ぶ』
参考URL:http://itpro.nikkeibp.co.jp/article/COLUMN/20070603/273403/
投稿日時 - 2008-02-19 19:31:42