CFileFindクラスのメンバ関数である、CFileFind.FindFile()を実行していくと、
仮想メモリ及び物理メモリが増加して行きます。
(念のため、APIであるFirstFind()でも同様)
CFileFindクラスのデストラクタもしくは、同メンバ関数のCFileFind.Close()
で後処理を実施していても現象は改善されません。
長期間連続稼動状態が続くとアプリケーションエラーが発生すると思われます。
(負荷試験を実施したら数日でアプリケーション異常発生)
定期的に、アプリケーションをリセットするしか方法はないのでしょうか?
(当該関数を使用することは絶対条件です。)
「開発環境」
OS:Windows2000/WindowsXP(SP2)
コンパイラ:VisualStudio6.0(SP6)
その部分のソースを出してもらえますか?
たぶん原因は他にある
製品向けプログラム中から、メモリ増加の原因が、FindFile()にあると
判断した際に、検証用に使用したコードを取急ぎ添付致します。
(別途、実際のコードも記載致します。)
パターン1
{
CString cStringFileName=c:\\Test\\*.*;
CFileFind cFileFind;
for( int iLoop=0; iLoop<100; iLoop++ )
{
cFileFind.FindFile( cStringFileName, 0);
cFileFind.Close();
}
}
パターン2
{
CString cStringFileName=c:\\Test\\*.*;
for( int iLoop=0; iLoop<100; iLoop++ )
{
CFileFind cFileFind;
cFileFind.FindFile( cStringFileName, 0);
}
}
はじめまして。
CFileFindは使ったこと無いであまりいい加減なことはいえませんが、
こんな感じではどうでしょうか^^;
if( filefind.FindFile(mych1) ) {
do {
b = filefind.FindNextFile();
} while( b );
filefind.Close();
}
注意
このプログラムだと100個検索したら終わりますので全部のファイル検索する場合は
FindNextFileの戻り値を使用して戻り値はBOOLなので簡単に使えると思います
はじめまして。
CFileFindは使ったこと無いであまりいい加減なことはいえませんが、
こんな感じではどうでしょうか^^;
if( filefind.FindFile(mych1) ) {
do {
b = filefind.FindNextFile();
} while( b );
filefind.Close();
}
注意
このプログラムだと100個検索したら終わりますので全部のファイル検索する場合は
FindNextFileの戻り値を使用して戻り値はBOOLなので簡単に使えると思います
うわ。。。連続投稿に。。。;
インデントぐちゃぐちゃですみません。。。;
CString cStringFileName=c:\\Test\\*.*;
CFileFind cFileFind;
bool ret;
if( cFileFind.FindFile(cStringFileName) ) {
do {
ret = cFileFind.FindNextFile();
} while( ret );
cFileFind.Close();
}
お邪魔しました。。。;
VC++7.1で追試しました。
100万回ループさせましたが、実行中メモリ使用量は一定、
右肩上がりに上昇「しません」。
VC++6ならではの現象?
だとすると Win32-APIでもそうなる理由がないな…
> CFileFindは使ったこと無いであまりいい加減なことはいえませんが、
> こんな感じではどうでしょうか^^;
> .....
これのどこが メモリ食いつぶし の対策になってんですか?
上記サンプルコードの主旨を誤解されているようなので、注記させて下さい。
上記サンプルコードは、FindFile()/FindNextFile()の使い方を皆さんにご教授頂きた
く記載したものではございません。
ファイル検索処理は、皆さんから示された方法を使用しております。。
FindFile()を実行すると、実行回数に比例して、メモリ使用量が増加して行く現象を
手っ取り早く、ご確認頂く為に作成したコードでございます。
当然、皆さんからご教授頂いております方法においてもこの処理を
連続的に実行させていけば、メモリ使用量が増加して行きます。
これが、マイクロソフトの不具合であれば、
FindFile()を使用している限りは、定期的にアプリをリセットするとかの
運用方法でカバーしなくてはならないと思っております。
マイクロソフトの技術情報では、過去事例など検索しても見当たらなかったので、
回避する手段とうお分かりになられている方がいらっしゃいましたら、
アドバイス願います。
> 当然、皆さんからご教授頂いております方法においてもこの処理を
> 連続的に実行させていけば、メモリ使用量が増加して行きます。
あれー? 100万回じゃ足りませんか?
目下一億回のループを回してますが、
メモリを食いつぶす気配が感じられないんすけど…
To επιστημηさんへ
検証ありがとうございます。
やはり、当方の環境下におきましては、タスクマネージャーのプロセスタブの
当該プロセスのメモリ使用量が、100回の実施に付き4kbyteづつ増加し続けます(><)
Windows2000でコンパイラ環境は同様のマシンで実施しても同一現象が発生。。。
当方も、.Netの環境で実施させて見ます。。
野球小僧さんのサンプルのように100回程度ループして1回目と100回目でメモリ使
用量が違うっていう程度では、リークとは断定できないんじゃないでしょうか?
検証用のプログラム全部と、どのように計測してリークと判断しているのかを示されたほ
うがいいと思いますが...
すみません。かなり勘違いしてました。
わたしも先ほど100万回ループさせてみました
環境は OS:XPSP2 VC++6.0Pですが
提示されたプログラムでは実行中メモリ使用量は一定、
上昇しませんでした。
ちなみに私がかいたプログラムのほうは、エラーっぽいですね^^;
> 当該プロセスのメモリ使用量が、100回の実施に付き4kbyteづつ増加し続けます(><)
私も検証。
パターン1(100ループ)をそのまま 1万回ループさせてみて、合計 100万回実行してみま
したが、その間、メモリ使用量は約 1.6MB, 仮想メモリサイズは約 550KB くらいで一定
していました。
OS:WindowsXP(SP2)
コンパイラ:VisualStudio6.0(SP6)
CWinApp theApp;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0);
for (int i = 0; i < 10000; i++)
{
CString cStringFileName=c:\\Test\\*.*;
CFileFind cFileFind;
for( int iLoop=0; iLoop<100; iLoop++ )
{
cFileFind.FindFile( cStringFileName, 0);
cFileFind.Close();
}
}
puts(end);
getchar();
return 0;
}
To Mellさんへ
実際に検証した方法としては、FindFile()/FindNextFile()の処理を実装している
アプリケーションで、本処理が、1回/1秒の割合で実行する負荷試験を行った結果
5日間で、メモリーリークが発生しました。
擬似的に、本処理をマスク(コメント)した状態で負荷試験を行った場合は、
メモリは安定しており、メモリリークは発生しませんでした。
このような経緯を経て、本処理に着目した結果メモリが解放されていないため、
おかしいと判断して、皆さんにお尋ねした次第です。
当方でも同僚の協力で、様々な環境下で実施した結果です。
★WindowsXP(SP1)/VisualStudio6(SP6)(本機にはVisualStudio7.1もある)→非再現
★WindowsXP(SP2)/VisualStudio6(SP6)(本機にはVisualStudio7.1はない)→再現
★Windows2000/VisualStudio6(SP6)(本機にはVisualStudio7.1はない)→再現
★WindowsXP(SP1)/VisualStudio7.1→非再現
★WindowsXP(SP2)/VisualStudio7.1→非再現
今のところ、VisualStudio6(SP6)のみを搭載した環境で再現している傾向があると
思われます。(もう少し、多種に渡り継続調査します。)
Mellさんの実行環境下には、VisualStudio7.1(.Net2003)はインストールされておりませ
んか??