2017-11-14 35 views
0

私はいくつかのレガシーコードをデバッグしています。ユーザー定義のCOMオブジェクトをロードし、ユーザーがその中の関数を呼び出して解放できるようにします。しかし、COMオブジェクトをロードしたりアンロードしたりするたびに、メモリがリークすることがわかりました。テストとして、コードをロードして実行するようにコードを変更し、プログラムの終了とリークがなくなるまでコードを再使用し続けます。ここCOleDispatchDriverを使用してCOMオブジェクトの動的な読み込みメモリを読み込む

は、関連するコードスニペットである:

このC++ codeisがCOMオブジェクトをロードするために呼び出され、pszProgId、ターゲットDLLを識別する文字列です。

COleDispatchDriver *pDispatchDriver = NULL; 
    pDispatchDriver = new COleDispatchDriver(); 
    if (!pDispatchDriver->CreateDispatch(pszProgId, &oleException)) 
    { 
    throw &oleException; 
    } 
    pDispatchDriver->m_bAutoRelease = TRUE; 
    *ppvObject = (void *) pDispatchDriver; 

void ** ppvObjectは、さまざまなオブジェクトを総称的に保持するために渡すポインタです。これははるかに大きな構造の一部です。 そして、COMオブジェクトを解放するときに私たちが呼び出すコードがあります。

我々はCOMオブジェクトを使用して行われた後、次のように、我々はそれを解放:

COleDispatchDriver* pDispatchDriver = (COleDispatchDriver*) (*((LONG_PTR*)(ppvObject))); 
pDispatchDriver->ReleaseDispatch(); 
delete pDispatchDriver; 

これは、約1メガすべての呼び出しをリークしています。対象のCOMオブジェクトはC#です。誰でも私たちが間違ってやっていることや私たちがやろうとしていることをするためのより良い方法を考えている?

これは、関連する場合に備えてVisualStudio 2015で作成しています。

再xMRi:

すでに述べたように、我々は効果なしにTRUEにそのフラグを変更してみました。サニティチェックとして、あなたのポストを読んだ後にもう一度やり直してみましたが、メモリリークを修正するために何もしませんでした。したがって、わかりやすくするために、コードを更新してTRUEに設定してください。これはほぼ確実に正しい値ですが、前述の同じメモリリークを示しています。

+0

C#コードが設計通りにメモリリークします。ガベージコレクタは、インタフェースポインタを解放するために実行したときに実行されます。このコードを100万回実行する単体テストを作成して、Release()呼び出しが問題ないことを確信し、プログラムがクラッシュする本当のメモリリークがあることを確認します。 perfview.exeの.NETメモリのperfカウンタを調べることで、GCの動作を確認できます。 –

+0

これを5,000回の繰り返しで実行し、クライアントプログラムのメモリが約5ギガヘルツに増加しました。私たちはその時点でそれを終了しなければなりませんでしたが、ガベージコレクションの遅延以上のものでした。 –

答えて

0

m_bAutoReleaseをFALSEに設定すると、ReleaseDispatchは何も行いません。実際には、このCOMオブジェクトのインスタンスを解放しないでください。

は、実装を参照してください:

void COleDispatchDriver::ReleaseDispatch() 
{ 
    if (m_lpDispatch != NULL) 
    { 
     if (m_bAutoRelease) 
      m_lpDispatch->Release(); 
     m_lpDispatch = NULL; 
    } 
} 

だからFALSEに自分をm_bAutoReleaseの設定に問題を作成しました。あなたがこれをやっている理由を確認してください。

LPDISPTACHポインタを直接取得してRelease()を呼び出すことができますが、これはm_bAutoReleaseTRUEの場合に実行する必要があります。

関連する問題