- PR -

GDIオブジェクトのリークでしょうか?

1
投稿者投稿内容
ナヲ
常連さん
会議室デビュー日: 2004/02/25
投稿数: 32
投稿日時: 2006-11-19 22:17
VB.NET 2003 で、Windowsアプリケーションの新規プロジェクトを作成し、
自動的にできたものに、Formを1つ追加し、Form1のボタン押下で、
Form2をモーダル表示させるだけのプログラムを以下のように組みました。

【Form1.vb】
  Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
      Dim fm As Form = New Form2
      fm.ShowDialog()
      fm.Dispose()
      fm = Nothing
  End Sub

Form1.vbに追加したコードは上記だけで、
Form2.vbはデザイナが作成したコードのみです。

このアプリケーションを実行し、Form1からForm2を表示し、From2を×ボタンで閉じる、ということを繰り返します。
このとき、タスクマネージャでGDIオブジェクトの数を見ていると、
From2を開いて閉じるという処理を一回行うごとに、
GDIオブジェクトが2個ずつ増えていくのですが、これは何なのでしょうか??
モーダル表示させるコードが間違っていますか?

よろしくお願いします。
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-11-20 10:34
引用:

ナヲさんの書き込み (2006-11-19 22:17) より:

このアプリケーションを実行し、Form1からForm2を表示し、From2を×ボタンで閉じる、ということを繰り返します。
このとき、タスクマネージャでGDIオブジェクトの数を見ていると、
From2を開いて閉じるという処理を一回行うごとに、
GDIオブジェクトが2個ずつ増えていくのですが、これは何なのでしょうか??


そのうちきれいになりませんか?
GC.Collect とかで。

VS2005 では Form の Dipose の段階でGDIオブジェクトは最初の状態に戻るようです。
VS2003 では Dispose しても GC が動くまではちょこちょこ増えていくみたいです。
_________________
かるあ のメモスニペット
ナヲ
常連さん
会議室デビュー日: 2004/02/25
投稿数: 32
投稿日時: 2006-11-20 11:03
返答ありがとうございます。
GC.Collectを入れたらきれいになりました!

しかし、別件というか実際に開発しているアプリでは、
GC.Collectを適宜入れているのですが、メモリは減っているように見えても、
GDIオブジェクト数は減っておらず、何度か繰り返すと、
MAXの10000に達して例外が発生してしまうという状況になり、調査していました。
GC.Collectで開放できるものであるならば、タイミングの問題でしょうか。
あと、GC.Collectで、世代指定していないのも原因かも知れません。
見直して見ます。
ありがとうございました。
ナヲ
常連さん
会議室デビュー日: 2004/02/25
投稿数: 32
投稿日時: 2006-11-20 11:35
スレッドの本文に記述したようなプログラムで、
Form2のdisposedイベントに、GC.Collect()を追加したら、きれいになりました。

しかし、Form2にMainMenuコントロールに追加し、
MenuItem1.Clickなど、関連したイベントプロシージャを追加すると、
GDIオブジェクトが残ってしまうようになります。
イベントプロシージャ内には何も記述せず、以下の2文を足すだけでなのですが。
Private Sub MenuItem1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles MenuItem1.Click

End Sub

何か関連があるのでしょうか?
同じような現象になった方いらっしゃいませんか?


甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2006-11-20 11:49
引用:

ナヲさんの書き込み (2006-11-20 11:03) より:
返答ありがとうございます。
GC.Collectを入れたらきれいになりました!


GC.Collectは負荷の高い処理ですので、あまり不用意に入れないように。

引用:

GC.Collectを適宜入れているのですが、メモリは減っているように見えても、
GDIオブジェクト数は減っておらず、何度か繰り返すと、
MAXの10000に達して例外が発生してしまうという状況になり、調査していました。
GC.Collectで開放できるものであるならば、タイミングの問題でしょうか。
あと、GC.Collectで、世代指定していないのも原因かも知れません。
見直して見ます。


COM等の非マネージドリソースの開放をきちんと行えているか、インスタンスへの参照を行ったままの変数が居ないか改めて精査してください。大抵はこのどちらかが原因かと。
ナヲ
常連さん
会議室デビュー日: 2004/02/25
投稿数: 32
投稿日時: 2006-11-20 12:21
返答ありがとうございます。
やはり、開放漏れ等が一番の原因と思い何度も見直したのですが、見つけられなかったので、
新規プロジェクトを作り自分でコーディングする部分を極力なくして検証していました。

結果、上のレスにあるとおり、MainMenuコントロールがらみのイベントプロシージャが
あるとどうもDGIオブジェクトが破棄されないようであることを見つけました。

そして、今、Form2のdisposedのプロシージャに、
MenuItemおよびMainMenuのdisposeを入れたところ、きれいに破棄されました!!

自分で作ったものは開放するように極力注意していたのですが、
デザイナで追加したコントロールなどは関係ないと思って無視していました。

デザイナが作ったものでも、明示的にdisposeしなければいけないものがあるのですね・・・。

また、GC.Collectも不用意に入れないように見直します。
ありがとうございました!
かるあ
ぬし
会議室デビュー日: 2003/11/16
投稿数: 1190
お住まい・勤務地: センガワ→ムサシノ
投稿日時: 2006-11-20 13:27
引用:

ナヲさんの書き込み (2006-11-20 12:21) より:

自分で作ったものは開放するように極力注意していたのですが、
デザイナで追加したコントロールなどは関係ないと思って無視していました。

デザイナが作ったものでも、明示的にdisposeしなければいけないものがあるのですね・・・。


勉強になります。

ここら辺と関係あるのかな?
http://www.ailight.jp/blog/kazuk/archive/2006/05/28/11473.aspx
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93732
_________________
かるあ のメモスニペット
ナヲ
常連さん
会議室デビュー日: 2004/02/25
投稿数: 32
投稿日時: 2006-11-20 13:41
引用:
ここら辺と関係あるのかな?
http://www.ailight.jp/blog/kazuk/archive/2006/05/28/11473.aspx
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=93732



初めて拝見しましたが、そんなことになってるんですね?!
正直、よくわからないのですが、なんか後々はまりそうで不安になります。

今回のMainMenuコントロールの件も、
イベントの処理を何も書いていない(=デザイナで追加しても使っていない)場合は、
特に問題が無いのに、イベントプロシージャを追加したとたん、GDIオブジェクトに影響をもたらす?!理由がまったくわかりません。
なので、MainMenuとMenuItemをdisposeしたことで本当に解決しているのかどうか・・・。

1

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