C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


(過去ログ 52 を表示中)
■29016 / )  Re[3]: Excelのメモリ開放について(遅延バインディング方式)
□投稿者/ 魔界の仮面弁士 (930回)-(2008/12/03(Wed) 12:56:25)
2008/12/03(Wed) 14:40:05 編集(投稿者)

No29014 (blueblur さん) に返信
> ただしVB6時代から多用された遅延バインディング方式では、
むしろ、型変換にともなって参照カウントが増加するなどの理由から、
レイトバインドの方が、解放が難しくなる事さえありえます。

例えば、
  Dim Hs As Excel.HPageBreaks = objSheet1.HPageBreaks
  Dim H As Excel.HPageBreak = Hs.Add(objRange)
  Marshal.ReleaseComObject(H)
  Marshal.ReleaseComObject(Hs)
  Marshal.ReleaseComObject(objRange)
  Marshal.ReleaseComObject(objSheet1)
ならば正しく解放されたコードが、参照設定無しだと
  Dim Hs As Object = objSheet1.HPageBreaks
  Dim H As Object = Hs.Add(objRange) 'ここで参照カウントが増加してしまう。
  Marshal.ReleaseComObject(H)
  Marshal.ReleaseComObject(Hs)
  Marshal.ReleaseComObject(objRange) 'そのため、ここで解放してもまだ一つ残っている…。
  Marshal.ReleaseComObject(objSheet1)
という結果になってしまった事がありました。
http://hpcgi1.nifty.com/MADIA/VBBBS2/wwwlng.cgi?print+200512/05120042.txt


> (VB.NETでも)InteropなしでNothingを与えるだけで開放できたようです。
だとしたら、それはただの偶然かも知れません。
(.NET 側のメモリ管理と COM のメモリ管理は別物です)

実際当方では、Nothing 代入による
 Sub Main()
   Dim o As Object = CreateObject("Excel.Application")
   o.Quit()
   MsgBox("これから解放します。", vbSystemModal)
   o = Nothing
   MsgBox("解放されていますか?", vbSystemModal)
 End Sub
というコードにおいて、タスクマネージャ上に「EXECEL.EXE」のプロセスが残ってしまう事を
確認しています。(アプリが終了すれば、続けて解放される可能性がありますけれども)


一方、ReleaseComObject を呼び出した場合においては、アプリを終了させずとも、
ReleaseComObject の呼び出しによって、タスクマネージャ上から「EXECEL.EXE」が
即座に消える事を確認しています。

 Sub Main()
   Dim o As Object = CreateObject("Excel.Application")
   o.Quit()
   MsgBox("これから解放します。", vbSystemModal)
   System.Runtime.InteropServices.Marshal.ReleaseComObject(o)
   MsgBox("解放されていますか?", vbSystemModal)
 End Sub
返信 編集キー/


管理者用

- Child Tree -