CreateProcessのメモリリークについて – プログラミング – Home

CreateProcessのメモリリー...
 
通知
すべてクリア

[解決済] CreateProcessのメモリリークについて


ゆか
 ゆか
(@ゆか)
ゲスト
結合: 21年前
投稿: 6
Topic starter  

お世話になります。初心者の ゆか です。
CreteProcessについて質問があります。

現在、MFCのexeから、コンソールアプリケーションを呼び出すテストツールを
作成しています。(下記がソースの一部)
GUIのボタンを押すと、コンソールアプリケーションがCreateProcessで呼び出され
10回ほど繰り返して終了するものです。
ところが正常に動作できることを確認したのですが、
タスクマネージャのプロセスタブで使用メモリを確認したところ
なぜか、メモリ使用率が増加して、開放されていません。
実行回数が増えれば増えるほど、メモリ使用率は増加し、
元にもどりません。(見た目にはリークしてるような動きです。)

ウィザードで作成して、以下のコードを貼り付けただけでも
メモリ使用量が増加しています。
もしお分かりの方いらっしゃいましたら
ご教授ください。

環境
Windows 2000 Server
Visual C++ 6.0(SP5)

※テストモジュールのため、エラー処理等は省いています。
[MFCアプリ]
void CCreateProcessAppDlg::OnButton1()
{
char lpExe[MAX_PATH] = {/*実行アプリケーションパス*/};
char lpArg[MAX_PATH] = {/*引数*/};

MessageBox(START,",MB_OK);

for(int i=0;i<10;i++)
{
CreateProcessFunc(lpExe,lpArg);
}

MessageBox(END,",MB_OK);
}

BOOL CreateProcessFunc(char *lpExe,char *lpArg)
{
PROCESS_INFORMATION pi;
STARTUPINFO si;

ZeroMemory(&si,sizeof(si));
si.cb=sizeof(si);

CreateProcess(lpExe,lpArg,NULL,NULL,FALSE,NORMAL_PRIORITY_CLASS,
NULL,NULL,&si,&pi);

CloseHandle(pi.hThread);

WaitForSingleObject(pi.hProcess,INFINITE);

CloseHandle(pi.hProcess);

return TRUE;
}

[コンソールアプリ]

#include stdafx.h
#include <windows.h>

int main(int argc, char* argv[])
{
MessageBox(NULL,HI,",MB_OK);
//実際にはここに処理を記述
     //処理を記述しなくてもリークする
return 0;
}

#別の掲示板で以下を参考にしてみては?というアドバイスをいただいた
のですが、以下はOSがガベージコレクタ的な動きをしてくれるので
問題ないということでしょうか?
http://www.mtakahashi.com/old/09325.html#09303


引用未解決
トピックタグ
アイススケーター
 アイススケーター
(@アイススケーター)
ゲスト
結合: 23年前
投稿: 280
 

その10回起動したアプリケーションは、ちゃんと終了させましたか。
終了させると元に戻るようですが


返信引用
ゆか
 ゆか
(@ゆか)
ゲスト
結合: 21年前
投稿: 6
Topic starter  

 返信ありがとうございます。
>その10回起動したアプリケーションは、ちゃんと終了させましたか。

 CreateProcessで起動するアプリケーションは、単純なコンソールアプリケーション
です。そのため、WaitForSingleObject(pi.hProcess,INFINITE);で制御が戻ってきた
時点で、コンソールアプリケーションは終了しているものと認識しています。
(間違っていたら申し訳ありませんが指摘をお願いします。)

また、上記のOnButton1() 関数を1回押しただけでは、増えませんが
3回~5回以上呼んだ場合に明らかに4KBづつ増えているようです。


返信引用
たく
 たく
(@たく)
ゲスト
結合: 23年前
投稿: 37
 

Explorerから、cmd.exeを連続して立ち上げてすべて終了させても、
すぐには元に戻りませんからねぇ


返信引用
ゆか
 ゆか
(@ゆか)
ゲスト
結合: 21年前
投稿: 6
Topic starter  

 返信ありがとうございます。
>Explorerから、cmd.exeを連続して立ち上げてすべて終了させても、
>すぐには元に戻りませんからねぇ

 ということは、いくらか待つと、メモリ使用量は低下するので
上記のコードは問題ないと理解してよろしいのでしょうか?

もし、時間をおけば低下するのであれば、どいうタイミングで
解放されるのでしょうか?


返信引用
wood
 wood
(@wood)
ゲスト
結合: 23年前
投稿: 895
 

あなたのプログラミング上で「CreteProcess」に問題があると考えたのはなぜでしょう
トータル的に見ての判断ではないのですか?

[コンソールアプリ]はメモリ消費がプログラム終了後すぐ開放されているの確認できて
ますか?
親プログラム抜きでで試してみましたか?

もし、時間をおけば低下するのであれば、どいうタイミングで
ほかの(あなたが作成した以外)のメモリを大量消費するPGを起動してみてください
本当に開放されていれば、メモリはリサイクルされるはずです


返信引用
ゆか
 ゆか
(@ゆか)
ゲスト
結合: 21年前
投稿: 6
Topic starter  

返信ありがとうございます。いろいろとアドバイスをいただき、大変助かります。

>あなたのプログラミング上で「CreteProcess」に問題があると考えたのはなぜでしょ

 
 CreateProcessに問題があると考えた経緯として、初めにあるプログラムを連続して使
用している
と、メモリ使用量が増加していることに気づきました。(タスクマネージャより)
そこで、プログラム上を切り分けて調べていき、CreateProcessを実行する関数を実行し
た後
メモリが解放されていないように見えましたので、その関数を切り抜いてテストプログ
ラムを
作成しました。(上記プログラムです。)
上記プログラムですが、MFCのウィザードでダイアログを作成し、ボタンを1つ配置しま
した。
そのボタンをクリックすると、中で上記のOnButton1()の関数が呼ばれ、上記コンソ
ールアプリケーション
が呼ばれます。
コンソールアプリケーションは、VCのウィザードでコンソールアプリケーションを作成
し、MessageBoxの
コードを記述しただけのものです。

そして、そのテストプログラムのボタンを1回、2回とクリックして、メモリ使用量が
どう変化していくか
調べました。
そうしたところ、1回目は別として、4~6回ほどクリックすると、メモリ使用量が4
KBほど増加しました。
その後、クリックを繰り返していくと、そのたびごとに4KBほど増加していきました。

そこでコードになにか問題があるのではということで、現在調べております。

>[コンソールアプリ]はメモリ消費がプログラム終了後すぐ開放されているの確認できて
ますか?
 
 コンソールアプリケーションのため、処理が終わるとプロセスが終了しまって、確認
できませんでした。
 (なにかよい方法があればご教授ください)
 そのため、別のコンソールアプリケーションを呼び出した場合も、同じ現象に遭遇し
たのと、
 コンソールアプリは、ウィザードで作成しメッセージ、main()にメッセージボック
スを記述しただけ
ですので、すぐに解放されると判断いたしました。

>メモリを大量消費するPGを起動してみてください

 残念ながら、私以外が作成したもので実験はしておりませんが、
 上記のプログラムを無限にループするようにし、Sleepである一定の時間休みながら実
行する
コードを記述して、一晩置いておいたのですが、増加しっぱなしでメモリ使用量が莫大
な量増えて
いました。
 今晩、ほかのもので実験してみたいと思います。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

もっと単純な話で、コンソール開いた状態で直接、コンソールアプリを実行してみて
確認すれば、コンソールアプリ自体がどうなのかは確認できそうな気がします。

簡単なバッチファイルでも作れば、連続で動かすことも可能でしょうし。
それをやったときにタスクマネージャー上でまったく同じ現象が起きるかどうかで
問題の切り分けがより進みませんか?

あと、膨大に増えた状態でWORDやEXCELのようなメモリを大量に消費するプログラムを
起動してみたときにタスクマネージャー上の状況はどう変化するでしょう。


返信引用
L
 L
(@L)
ゲスト
結合: 21年前
投稿: 6
 

プログラムの最初と最後で

SetProcessWorkingSetSize(GetCurrentProcess(), 0xFFFFFFFF, 0xFFFFFFFF);
#または EmptyWorkingSet 関数

を実行し、このときの「メモリ使用量」および「仮想メモリサイズ」を比較してみた
ら、どうでしょう。
それでも回数に比例して増加するなら、本当にリークしているんじゃなかろうか?


返信引用
ゆか
 ゆか
(@ゆか)
ゲスト
結合: 21年前
投稿: 6
Topic starter  

 返信ありがとうございます。
>SetProcessWorkingSetSize(GetCurrentProcess(), 0xFFFFFFFF, 0xFFFFFFFF);

 以上を記述して、テストプログラムを実行いたしました。
すると、以前に発生していた4KBごとにメモリ使用量が増加する現象が
起きなくなりました。
上記の結果からすると、単純にシステムが解放するタイミングを待っている
(または、解放したけれども更新されていない?)ということだと理解いたしました。
いろいろお騒がせした状態になってしまいまして申し訳ありません。
多くの方々にアドバイスをいただき大変ありがとうございました。

#1点だけ、どういうタイミングで解放するのかという疑問が残るのですが
#いろいろ調べて、わかればご報告いたします。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました