- PR -

System.Windows.Form.Timerのメモリ消費

1
投稿者投稿内容
よしこ
会議室デビュー日: 2006/03/30
投稿数: 5
投稿日時: 2006-03-30 16:33
FormにTimerコントロールを配置してフォームを起動し、
タスクマネージャでメモリ使用量を監視していると、
2秒で8KBずつぐらい増加していることに気がつきました。
(メモリ使用量の増加にともなって、増加速度は遅くなり、最終的に止まります。)
開発環境はVisualStudio.NET 2003で.NET Framework 1.1です。

Timerコントロールのプロパティはデザイナで以下のように設定しています。
Interval = 10
Enabled =True

原因はなんでしょうか?また解決方法はありませんでしょうか?
宜しくお願い致します。


【補足】
Win32APIのSetTimerを使用してもメモリをどんどん消費しました。
以下にソースの一部を転載します。

[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern IntPtr SetTimer(IntPtr hWnd, int nIDEvent, int uElapse, TimerProc lpTimerFunc);
[DllImport("user32.dll", CharSet=CharSet.Auto, ExactSpelling=true)]
public static extern bool KillTimer(IntPtr hwnd, int idEvent);

public delegate void TimerProc(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam);

private int timerid;
private void Form1_Load(object sender, System.EventArgs e)
{
 TimerProc proc1 = new TickLoop.Form1.TimerProc(this.timer_Tick_native);
 timerid = (int)SetTimer(this.Handle,0,1,proc1);
}

private int count=0;
private void timer_Tick_native(IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam)
{
 count = ++count % 100;
}

private void btnDestroy_Click(object sender, System.EventArgs e)
{
 KillTimer(this.Handle,timerid);
}

同様のアプリケーションを、ネイティブコードで作成すると、
メモリは消費されませんでした。←VC++で確認
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-30 16:41
引用:

よしこさんの書き込み (2006-03-30 16:33) より:

FormにTimerコントロールを配置してフォームを起動し、
タスクマネージャでメモリ使用量を監視していると、
2秒で8KBずつぐらい増加していることに気がつきました。
(メモリ使用量の増加にともなって、増加速度は遅くなり、最終的に止まります。)


この手の話題は 2 ヶ月に 1 度くらいの割合で目にするのですが、
GC が回収に来ていない以上、どうこう言える問題じゃないですよね。

見るにしても、「仮想メモリサイズ」も見ないと意味がないです。
意味がわからなければ、その問題の Form を最小化してみてください。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
Hongliang
ぬし
会議室デビュー日: 2004/12/25
投稿数: 576
投稿日時: 2006-03-30 17:04
メモリのことはどうでもいいとして、
引用:

private void Form1_Load(object sender, System.EventArgs e)
{
 TimerProc proc1 = new TickLoop.Form1.TimerProc(this.timer_Tick_native);
 timerid = (int)SetTimer(this.Handle,0,1,proc1);
}


これじゃ TimerProc デリゲートオブジェクトが参照が無くなったと判断されて GC の対象になりますよ。
GC が走ればデリゲートオブジェクトが回収されて、処理するハンドラが無くなります。
フォームのフィールドに置いておけば、意図的に null を代入しない限りフォームが GC されるまで寿命が持ちます。
// ところでこれも GC によってオブジェクトの移動が発生した場合にアンマネージドがハンドルできなくなるような気がするんだけどどうなんでしょ。
// 一応私は念のために GCHandle 使ってますけど。
よしこ
会議室デビュー日: 2006/03/30
投稿数: 5
投稿日時: 2006-03-30 17:21
じゃんぬねっとさん
すばやい回答をありがとうございます

引用:

じゃんぬねっとさんの書き込み (2006-03-30 16:41) より:

この手の話題は 2 ヶ月に 1 度くらいの割合で目にするのですが、
GC が回収に来ていない以上、どうこう言える問題じゃないですよね。



なるほど。
タイマープロシージャ内で、
System.Diagnostics.GC.Collect()を呼んで強制的にGCに回収させようとすると
メモリの使用量が増加しつづけることはなくなりました。

とはいえ、なぜメモリ使用量が増えるのか気になります。

引用:

見るにしても、「仮想メモリサイズ」も見ないと意味がないです。
意味がわからなければ、その問題の Form を最小化してみてください。


勉強不足で申し訳ありません。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=25982&forum=8&1
をみてよくわかりました。

この問題の場合、「メモリ使用量」は増加しても
「仮想メモリサイズ」は増加しません。
で、Formを最小化してみると、「メモリ使用量」のみ激減しましたが、
あいかわらず「メモリ使用量」は増加し続けます。

つまりはどういうことなのでしょうか?
よしこ
会議室デビュー日: 2006/03/30
投稿数: 5
投稿日時: 2006-03-30 17:25
Hongliangさん
返答ありがとうございます。

引用:

Hongliangさんの書き込み (2006-03-30 17:04) より:

これじゃ TimerProc デリゲートオブジェクトが参照が無くなったと判断されて GC の対象になりますよ。
GC が走ればデリゲートオブジェクトが回収されて、処理するハンドラが無くなります。
フォームのフィールドに置いておけば、意図的に null を代入しない限りフォームが GC されるまで寿命が持ちます。
// ところでこれも GC によってオブジェクトの移動が発生した場合にアンマネージドがハンドルできなくなるような気がするんだけどどうなんでしょ。
// 一応私は念のために GCHandle 使ってますけど。


なるほど。。
参考にしたソースにはGCHandle.Alloc(procedule1)とFree()を使用していましたが、
よく考えずに消してしまいました^^;
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-30 17:37
引用:

よしこさんの書き込み (2006-03-30 17:21) より:

タイマープロシージャ内で、
System.Diagnostics.GC.Collect()を呼んで強制的にGCに回収させようとすると
メモリの使用量が増加しつづけることはなくなりました。
とはいえ、なぜメモリ使用量が増えるのか気になります。


回収すれば増えることはなくなったんですよね。
よしこさんの仮定を信じて話すのであれば、回収していないから増えるんでしょう。

引用:

つまりはどういうことなのでしょうか?


> 見るにしても、「仮想メモリサイズ」も見ないと意味がないです。

とあるように "せめて" 双方を見ないと早計な判断をしてしまう可能性があるということです。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
よしこ
会議室デビュー日: 2006/03/30
投稿数: 5
投稿日時: 2006-03-30 18:03
引用:

じゃんぬねっとさんの書き込み (2006-03-30 17:37) より:

よしこさんの仮定を信じて話すのであれば、回収していないから増えるんでしょう。


回収していないから増えるのですか。
どうも私は基本的な部分を理解できていないようですね・・

引用:

> 見るにしても、「仮想メモリサイズ」も見ないと意味がないです。

とあるように "せめて" 双方を見ないと早計な判断をしてしまう可能性があるということです。


なるほど、そういう意味でしたか。
ご指摘ありがとうございます。次からどちらも確認します^^
1

スキルアップ/キャリアアップ(JOB@IT)