■29016 / inTopicNo.4) |
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
|
|