2014-02-10 3 views
1

У меня есть приложение для тестирования COM inproc, которое использует IXMLDOMDocument для записи данных и отправки их обратно в COM-клиент. Я использую get_xml() для получения BSTR. Но когда приложения заканчиваются, он потребляет почти> 20 МБ памяти, а если я не использую COM-сервер inproc, он использует < 1 МБ. метод
Мой COM сервер ИнтерфейсIXMLDOMDocument memory Leak Issue

[ 
    object, 
    uuid(BF798ED1-DCDD-4B29-B552-3A17F1D7E4CF), 
    dual, 
    nonextensible, 
    pointer_default(unique) 
] 
interface IMoLauncher : IDispatch{ 
    [id(1)] HRESULT GetXML([out] BSTR* bStr); 
}; 

это код

STDMETHODIMP CMoLauncher::GetXML(BSTR* bStr) 
{ 
    AFX_MANAGE_STATE(AfxGetStaticModuleState()); 
    BOOL result = FALSE; 
    IXMLDOMDocument* pDoc = NULL; 
    HRESULT hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, 
            IID_IXMLDOMDocument, (void**)&pDoc); 

    if (SUCCEEDED(hr)) 
    { 
     result = TRUE; 
     IXMLDOMNode* pEntityNode = InsertDOMElement(pDoc, NULL, L"Entity", NULL); 
     SerializeXML(pDoc, pEntityNode); 
     pDoc->get_xml(bStr); 
     pDoc->Release(); 
    } 
    return result; 
} 

и использование кода в клиенте

CoInitialize(NULL); 
IMoLauncher* launcher = NULL; 
IUnknown* unknown = NULL; 
HRESULT result = CoCreateInstance(CLSID_MoLauncher,NULL,CLSCTX_INPROC_SERVER,IID_IMoLauncher,(void**)&launcher); 
if(result==S_OK) 
{ 
    for(int i=0;i<iterationCount;i++) 
    { 
     BSTR bStr; 
     launcher->GetXML(&bStr); 
     printf("Iteration %d\n",i); 
     ::SysFreeString(bStr); 
    } 
} 
launcher->Release(); 
CoUninitialize(); 
+0

VS решение 2010 можно загрузить с https://drive.google.com/file/d/0BwWrSUCFF-AXeGZoZ0tQR1lLbVk/edit?usp=sharing –

ответ

0

IXMLDOMNode*, возвращенный с CMoLauncher::InsertDOMElement, никогда не выпускается, это большая утечка.

Вам нужно добавить Release вызовов для:

  1. Первого InsertDOMElement вызова в CMoLauncher::SerializeXML.
  2. В InsertDOMElement вызовы в петле в одной и той же функции (добавление локальной переменной для того, чтобы сделать это (возвращаемое значение InsertDOMElement)
  3. InsertDOMElement вызова в CMoLauncher::GetXML (замечен xMRI)
+0

благодарит за вашу помощь –

+0

@RizwanHanif Вы радушны. Наслаждайтесь своей новой репутацией. – manuell

1

вам нужно освободить pEntityNode тоже!

Каждый COM-указатель, возвращаемый интерфейсом или функцией COM, должен быть освобожден. Вы можете использовать интеллектуальные указатели, чтобы избежать таких ошибок.