検証の動機Qiitaでこういう記事を書きました。COMオブジェクトであるMicrosoft.Office.Interop.Wordを使用した.NETアプリを作成した、というものです。Qiitaタイトル通りの内容ですが、内部で使用している変換にはMicrosot.Office.Interop.Wordを使用しています。Google先生に聞くとこの辺りの情報は豊富ですし、COMオブジェクト故に「Microsot.Offic...qiita.com昔から知られていることですが、.NETからCOMオブジェクトの呼び出しはラッパーを仲介するため、処理のオーバーヘッドが高くなります。マネージドなライブラリがあるなら、そちらを用いたほうが効率が良いです。Microsoft)ですが、どうしてもCOMの使用が必要な場面もあります。マネージドMS以外のベンダー(Oracleとか)では「管理対象」と訳している場合があります(反対語は「非管理対象」)。マネージドコードと言う場合はCLRによって管理されるコードのことを指し、メモリ自動管理の対象にもなります。反対は「アンマネージド」で、C/C++などで記述されたコードがこれに当たる。COMオブジェクトもアンマネージドなコードで記述されたライブラリ。Modelの略ですが、昔のVB6.0の時代ではよく使われていたもので、ソフトウェアの再利用が可能になるもの。今回の場合で言えば、WordのAPIがこのCOMオブジェクトに当たります。CLRのメモリ自動管理の対象になりませんので、開放処理を書いてやる必要があります。コード本サイトのプロフィールのエリアにGitHubのリンクがありますが、一応、ソリューション全体のソースは以下です。(GitHub)メモリ開放が必要なのは、以下の「変換」ボタン押下時の、WordファイルからPDFへの変換処理の箇所です。下の、finally句のところです。Cursors.Default;}GC.GetTotalMemoryは割り当てられているメモリのバイト数を返します。Wordで実施しました。開放処理のコードを入れない場合Marshal.ReleaseComObjectだけでGC.Collect()を入れない場合です。word.Quit();Marshal.ReleaseComObject(doc);Marshal.ReleaseComObject(docs);Marshal.ReleaseComObject(word);結果:前:505,092後:521,476増加していますね。解放処理がなされていないようです。最後にGC.Collect()MSのドキュメントのサンプル通りの書き方です。word.Quit();Marshal.ReleaseComObject(doc);Marshal.ReleaseComObject(docs);Marshal.ReleaseComObject(word);GC.Collect();結果:前:505,092後:211,684ちゃんと開放してくれているようですね。前後にGC.Collect()開放処理の前後だと差はあるのでしょうか。word.Quit();Marshal.ReleaseComObject(doc);Marshal.ReleaseComObject(docs);Marshal.ReleaseComObject(word);GC.Collect();結果:前:505,092後:196,044後だけの時よりも、占有領域が減っているようです。最後にGC.Collect()とGC.WaitForPendingFinalizers()これを試した理由は、この記事を見たからです。Part1上の記事の例ではベストプラクティスとして、GC.Collect();GC.WaitForPendingFinalizers();GC.Collect();を開放の前後に入れていますが、今回は後だけの場合と前後の場合も検証してみます。word.Quit();Marshal.ReleaseComObject(doc);Marshal.ReleaseComObject(docs);Marshal.ReleaseComObject(word);GC.Collect();GC.WaitForPendingFinalizers();GC.Collect();結果:前:505,092後:195,104GC.Collect()だけの時より減少していますね。前後にGC.Collect()とGC.WaitForPendingFinalizers()ベストプラクティスとして挙げられていた書き方。word.Quit();Marshal.ReleaseComObject(doc);Marshal.ReleaseComObject(docs);Marshal.ReleaseComObject(word);GC.Collect();GC.WaitForPendingFinalizers();GC.Collect();結果:前:505,092後:195,104後だけの場合と変化はありません。結論COMオブジェクト開放の際は、Marshal.ReleaseComObject(word)だけでなく、ガーベジコレクションを強制的に走らせる処理を行う必要がある、ということになりますね。WaitForPendingFinalizersについては、以下を参照。メソッドしかし、前後にガベコレを強制させるコードは、かなり可読性がよくないな...。5.0(ARM64bit版)をインストールする方法の記録です。FrameworkのWebBrowserコントロールで、表示仕様をデフォルトのIE7の状態から最新版(IE11・Edge)に変える方法を説明します。.NETGitHubに暗号化ツールとハッシュ値計算ツールを公開コンソールアプリの暗号化ツール(AES)とハッシュ値計算・検証ツールをGItHubで公開しましたので、告知です。大したものではありませんが。Driverを使います。Clientのインストールなしで使用できます。本サイトについて情シスSE(開発業務もしています)。本サイトは主に勉強のアウトプットが目的です。Reserved.ホーム検索トップサイドバータイトルとURLをコピーしました。