- - PR -
GetTotalMemoryのメモリ使用量とタスクマネージャのメモリ使用量について
投稿者 | 投稿内容 | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2007-05-08 18:03
これは違うと思います。 変数 basp の参照を解放しているだけです。 オブジェクトを解放しているわけではありません。 また basp がローカル変数の場合、ほとんど意味がありません。 Private メンバであれば GC の回収をある程度期待しやすくなると思いますが、そういった場面が想定できません。
"オブジェクトの開放" というのはおそらく参照の解放でしかないと思いますが、 そんなことよりも、COM の参照カウントの解放の方が大切です。 というより、リソースとメモリを混同していませんか?
basp が Nothing なのに ReleaseComObject メソッドをどう実行するおつもりなのでしょうか? 参照カウントのデクリメント対象がすでにないわけで... COM との連携であっても GC.Collect メソッドなんていうのは、積極的に使うものではないです。
他から参照されていなければ、ラッパですから回収対象にはなりますよ。 http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=29278&forum=7&start=13 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||||||||||
|
投稿日時: 2007-05-08 18:34
そうなのですか!! http://www.b21soft.co.jp/basp21/basp21puser.html や http://www.b21soft.co.jp/basp21/basp21puser.html を見てオブジェクトの解放だと思っていました。
ということは理論的には、basp=nothingとSystem.GC.Collect() をコメントにしてMarshal.ReleaseComObject(basp)を実行することでCOM の参照カウントが解放されて、 他から参照されていないので、ガベージの回収対象にはなり解放されるということですよね?
| ||||||||||||||||
|
投稿日時: 2007-05-08 20:37
.NET CLR は COM を直接扱うことができません。 そのため 'basp' というのは COM のラッパ オブジェクトの参照になります。 リンク先 (2 つとも同じですね) は VBScript など COM を扱うことができる言語でのお話ですね。 つまり、参照カウント法の場合の話ですね。 これらは、参照カウントがデクリメントされると自動的に Terminate されます。 このように CLR と COM を混同していることが誤りなのだと思います。
はい、GC の気まぐれなタイミングで回収されるでしょう。 _________________ C# と VB.NET の入門サイト じゃんぬねっと日誌 | ||||||||||||||||
|
投稿日時: 2007-05-08 22:07
GCというのは、基本的にはマネージメモリが足りなくなったときに発動されます。
逆に言うと、マネージメモリが十分に余っている間は、GCは起こりません。 COMその他、アンマネージのリソースを使用する場合、これらが使用するメモリは アンマネージメモリであり、マネージメモリではありません。 アンマネージリソースが解放されず、アンマネージメモリが大量に消費されたままの 状態になっても、マネージメモリが空いている間はGCは発生しません。 COMラッパーの参照をnothingにしたり、メソッドから抜けて参照が開放されたとき、 参照はすでになくなっていますから、COMオブジェクトなどはGCで開放される対象には なっています。 しかし、GCの対象になったりソースが実際に開放されるのは、GCが発動されたときです(COMの場合はさらにファイナライザが実行されたときかな)。 GC.Collectを明示的に実行すると開放されるのはこのためです。 マネージメモリが空いている間はGCが自動的に発動されないため、 明示的にGCを実行してやらないと開放されないままになってしまうわけです。 ReleaseComObjectなどを実行すると、参照カウントがデクリメントされます。 参照カウントが0になると、もはやそのCOMオブジェクトは不要だと分かるので、 その場でCOMオブジェクトは開放されます。 COMはアンマネージリソースなので、GCを待たずに即座にリソースを開放できます。 しかし、マネージの世界のCOMラッパーはマネージオブジェクトなので、 次にGCが発動するまで開放されません。 しかしながら、COMラッパーはもはやマネージメモリというリソースしか使用していません。 マネージメモリが不足するとすぐにGCが発動するため、リソース不足の実害が出る前に自動的に開放することができるわけです。 ちなみにアンマネージメモリを使用していることをGCに伝えるためのAddMemoryPressure というメソッドもあります(2.0以降)。 アンマネージメモリばかりが使用される場合に、GCが全く発動されないことを避けるための機能です。 | ||||||||||||||||
|
投稿日時: 2007-05-08 22:46
ちょっと、違う。様な気がする。 アンマネージリソースは、明示的に解放しなければ、GC.Collect でも解放されません。 たとえば、ファイルを開きます。このファイルハンドルを憶えている変数に Nothing を代入します(COM オブジェクトではないので)。そして、GC.Collect します。このとき、ファイルが閉じられるのは、ファイナライザで解放処理が呼ばれているからです。.NET Framework として提供されているクラスではおおよそファイナライザで解放処理が行われると仮定してかまわないと思います。しかし、それ以外のものでは、期待してはいけません。 ですから、アンマネージリソースを使う場合は、まずドキュメントを確認し、どのように確保して、どのように解放するか、確認しなければなりません。 _________________ | ||||||||||||||||
|
投稿日時: 2007-05-09 10:29
じゃんぬねっとさん、なちゃさん、Jittaさん返信ありがとうございます。
また返信が遅くなり申し訳ありません。 じゃんぬねっとさんに教えていただいたとおりプログラムを修正したらうまいこといきました。ありがとうございました。 またなちゃさん、Jittaさんの返信の内容を読むことで大変勉強になりました。 皆様、本当にありがとうございました。心から感謝いたします。 |