- PR -

COMオブジェクトの参照カウントを"0"にしないでおく場合

投稿者投稿内容
アムオタ
会議室デビュー日: 2007/06/28
投稿数: 5
投稿日時: 2007-06-28 16:59
初めて投稿させていただきます。

VB2003で作成したEXCELのCOMオブジェクトを使ったアプリで、COMオブジェクトへの参照カウントが"0"にならないままの状態でそのアプリを正常終了させた場合は、どのような事になるのでしょうか。

下記のMSDNのコメントにある、COMをプログラミングする立場からは、「参照カウントがいつまでも 0 にならず、オブジェクトは半永久的にメモリに残っていることになる。 」と書かれてますので、COMオブジェクトを使用する側からすると、参照カウントを"0"にしないでおくとメモリを消費し続けていると考えてもいいのでしょうか?

COMオブジェクトについてはあまり詳しくありません。
ご教授お願いします。



「COM プログラミングでは参照カウントを正しく処理することが非常に重要である。この処理を正しく行わないと、メモリ リークが生じやすくなる。COM プログラマが最も冒しやすいミスの 1 つが、インターフェイスの解放し忘れである。インターフェイスが解放されないと、参照カウントがいつまでも 0 にならず、オブジェクトは半永久的にメモリに残っていることになる。 」
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpdx8_c/hh/directx8_c/_dx_managing_a_com_object_s_lifetime_dxintro.asp
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-06-28 18:47
引用:

VB2003で作成したEXCELのCOMオブジェクトを使ったアプリで、COMオブジェクトへの参照カウントが"0"にならないままの状態でそのアプリを正常終了させた場合は、どのような事になるのでしょうか。



そのアプリが終了した時の状態で、Excel が居残ります。

Excel を終了するためには、Excel 関連のオブジェクトの参照カウントを正しい順序ですべて解放した後、Excel.Application の Quit() メソッドを呼び出します。

引用:

COMオブジェクトを使用する側からすると、参照カウントを"0"にしないでおくとメモリを消費し続けていると考えてもいいのでしょうか?



まぁ、そうなりますね。

プログラムの実行にはメモリの消費がつき物ですから、Excel が居残るということはその分のメモリは Excel が終了するまで占有され続けます。
アムオタ
会議室デビュー日: 2007/06/28
投稿数: 5
投稿日時: 2007-06-29 19:06
渋木さん、早々にご回答ありがとうございます。

気になりますのは、EXCELのプロセスがタスクバーから消えたら、参照カウントが"0"でなくても参照されたオブジェクトはメモリーから開放される、かどうかということです。

たとえば、荒っぽいコーディングですが、
コード:
Dim xlApp As New Excel.Application
Dim xlBook As Excel.Workbook
Dim xlsFolder As String
Dim xlsFile As String

  xlsFolder = "C:/"
  xlsFile = "dummy.xls"

  xlBook = xlApp.Workbooks.Open(xlsFolder & "/" & xlsFile, , True)
  xlBook.Close()
  xlApp.Quit()

  If Not xlBook Is Nothing Then
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlBook)
  End If
  If Not xlApp Is Nothing Then
    System.Runtime.InteropServices.Marshal.ReleaseComObject(xlApp)
  End If


の場合に参照カウントが"0"になっていません。
処理終了時にタスクマネージャーのプロセスにEXCELのプロセスが残っています。
ですが、このコーディングを施したアプリを終了させると、タスクマネージャーのプロセスは無くなります。
この現象をどうとらえたらいいんでしょうか。
(1)プロセスが無くなったので参照カウントも"0"になった。のでしょうか。
(2)それとも、プロセスは無くなったが参照カウントは"0"になってない。のでしょうか。

もし、(2)であれば、「・・参照カウントがいつまでも 0 にならず、オブジェクトは半永久的にメモリに残っていることになる。」ということになります。
プロセスとメモリーの関連が良く分かってませんので、よく理解ができません。
一般的にプロセスが消えたらメモリー上からも消えていると考えてしまいます。

この現象をどう解釈したらよいか、解説いただければありがたいです。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-06-30 11:30
引用:

この現象をどうとらえたらいいんでしょうか。



バグです。

コード:
  xlBook = xlApp.Workbooks.Open(xlsFolder & "/" & xlsFile, , True)



で Workbooks オブジェクトを暗黙に参照していて、その参照が解放されていません。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-06-30 11:35
引用:

ですが、このコーディングを施したアプリを終了させると、タスクマネージャーのプロセスは無くなります。



アプリケーション終了時にアプリケーションで使用していたオブジェクトの一斉廃棄が起こり、その一環として暗黙参照で使用されていたオブジェクトも解放されて、結果 Excel オブジェクトの参照カウントが0になったので、ようやく Excel が正常したんです。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2007-06-30 13:44
一斉廃棄の件ですが、COM ラッパ オブジェクトという意識がないと混同してしまうかもしれないですね。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-06-30 17:21
引用:

一斉廃棄の件ですが、COM ラッパ オブジェクトという意識がないと混同してしまうかもしれないですね。



お。最初かいてたんだけど、推敲してたら削っちゃってました (^^;

アプリケーション終了時に未廃棄だった .NET オブジェクトの一斉廃棄が起こり、その一環として暗黙参照で使用されていた COM オブジェクトのラッパが解放→未解放になっていた Excel の COM オブジェクトが解放されて、ようやく Excel が正常した。

て感じですね。
アムオタ
会議室デビュー日: 2007/06/28
投稿数: 5
投稿日時: 2007-07-02 15:51
渋木さん、じゃんぬねっと さん、ご回答ありがとうございます。

「参照カウントがいつまでも 0 にならず、オブジェクトは半永久的にメモリに残っていることになる。 」(MSDN)
は、COM ラッパ オブジェクトの一斉廃棄が行われるとメモリから開放されるんですね。

色々情報をいただき、ありがとうございました。
勉強になりました。
また、機会がありましたらよろしくお願いします。

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