CoInitialize, CoCreateInstance и потоки
От: Vorobiev Sergei Россия  
Дата: 08.07.04 13:59
Оценка:
Привет, Всем!

Как полностью освободить ресурсы после того как COM-объект больше не нужен? В приведенном примере память после завершения работы функции потока не освобождается. Если убрать вызов CoCreateInstance, то все нормально. COM-объект ничего не делает — заготовка сгенерированная CB6. Тестовая программа тоже на CB6.

#include <utilcls.h>
#include <atl\atlbase.h>
#include <process.h>
#include "EmptyCOMObject_TLB.h"

IEmptyCOMClass* pObject;

unsigned __stdcall ThreadFunc(void *apParam)
{
  CoInitialize(NULL);
  ::CoCreateInstance(CLSID_EmptyCOMClass, NULL, CLSCTX_INPROC_SERVER, IID_IEmptyCOMClass, (void**)&pObject);
  pObject->Release();
  CoUninitialize();
}

int main(int argc, char* argv[])
{
  for (int i = 0; i < 100; i++)
  {
    unsigned nThread;
    HANDLE hThread;
    hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, NULL, 0, &nThread);
    WaitForSingleObject(hThread, INFINITE);
    CloseHandle(hThread);
  }
  return 0;
}
... << Rsdn@Home 1.1.4 beta 1 >>
Re: CoInitialize, CoCreateInstance и потоки
От: rus blood Россия  
Дата: 08.07.04 14:02
Оценка:
Здравствуйте, Vorobiev Sergei, Вы писали:

VS>Привет, Всем!


Попытка №1

CoFreeUnusedLibraries
Имею скафандр — готов путешествовать!
Re[2]: CoInitialize, CoCreateInstance и потоки
От: Vorobiev Sergei Россия  
Дата: 09.07.04 06:16
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>Попытка №1


RB>
RB>CoFreeUnusedLibraries
RB>


Это не помогло. Похоже, что дело именно в вызове CoInitialize, потому что, если функцию потока переписать так, то память растет одни раз при запуске, затем находится на одном уровне и после цикла уменьшается. А если нужно периодически создавать поток?

unsigned __stdcall ThreadFunc(void *apParam)
{
  CoInitialize(NULL);

  for (int i = 0; i < 100; i++)
  {
    ::CoCreateInstance(CLSID_EmptyCOMClass, NULL, CLSCTX_INPROC_SERVER,
      IID_IEmptyCOMClass, (void**)&pObject);
    pObject->Release();
    cprintf(".");
    Sleep(100);
  }

  CoUninitialize();
}
... << Rsdn@Home 1.1.4 beta 1 >>
Re[3]: CoInitialize, CoCreateInstance и потоки
От: jabber  
Дата: 09.07.04 11:33
Оценка:
Здравствуйте, Vorobiev Sergei, Вы писали:

VS>Здравствуйте, rus blood, Вы писали:

а каким образом вы память считаете?
в профайлере или в sysinfo?


RB>>Попытка №1


RB>>
RB>>CoFreeUnusedLibraries
RB>>


VS>Это не помогло. Похоже, что дело именно в вызове CoInitialize, потому что, если функцию потока переписать так, то память растет одни раз при запуске, затем находится на одном уровне и после цикла уменьшается. А если нужно периодически создавать поток?


VS>
VS>unsigned __stdcall ThreadFunc(void *apParam)
VS>{
VS>  CoInitialize(NULL);

VS>  for (int i = 0; i < 100; i++)
VS>  {
VS>    ::CoCreateInstance(CLSID_EmptyCOMClass, NULL, CLSCTX_INPROC_SERVER,
VS>      IID_IEmptyCOMClass, (void**)&pObject);
VS>    pObject->Release();
VS>    cprintf(".");
VS>    Sleep(100);
VS>  }

VS>  CoUninitialize();
VS>}
VS>
... << Rsdn@Home 1.1.4 beta 1 >>
Re: CoInitialize, CoCreateInstance и потоки
От: VictorProg  
Дата: 09.07.04 12:10
Оценка: -1
Здравствуйте, Vorobiev Sergei, Вы писали:

VS>Привет, Всем!


VS>Как полностью освободить ресурсы после того как COM-объект больше не нужен? В приведенном примере память после завершения работы функции потока не освобождается. Если убрать вызов CoCreateInstance, то все нормально. COM-объект ничего не делает — заготовка сгенерированная CB6. Тестовая программа тоже на CB6.


VS>
VS>#include <utilcls.h>
VS>#include <atl\atlbase.h>
VS>#include <process.h>
VS>#include "EmptyCOMObject_TLB.h"

VS>IEmptyCOMClass* pObject;

VS>unsigned __stdcall ThreadFunc(void *apParam)
VS>{
VS>  CoInitialize(NULL);
VS>  ::CoCreateInstance(CLSID_EmptyCOMClass, NULL, CLSCTX_INPROC_SERVER, IID_IEmptyCOMClass, (void**)&pObject);
VS>  pObject->Release();
VS>  CoUninitialize();
VS>}

VS>int main(int argc, char* argv[])
VS>{
VS>  for (int i = 0; i < 100; i++)
VS>  {
VS>    unsigned nThread;
VS>    HANDLE hThread;
VS>    hThread = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, NULL, 0, &nThread);
VS>    WaitForSingleObject(hThread, INFINITE);
VS>    CloseHandle(hThread);
VS>  }
VS>  return 0;
VS>}
VS>



День добрый. Я так думаю, что Release метод должен полностью очистить ресурсы, убрать все ссылки на объект и выполнить ему delete. Попробуй использовать CoInitializeEx(NULL, COINIT_MULTITHREADED), это расширенный вариант, специально для мультитредных задач. Должно помочь.
Re[4]: CoInitialize, CoCreateInstance и потоки
От: Vorobiev Sergei Россия  
Дата: 09.07.04 12:27
Оценка:
Здравствуйте, jabber, Вы писали:

J>Здравствуйте, Vorobiev Sergei, Вы писали:


VS>>Здравствуйте, rus blood, Вы писали:

J>а каким образом вы память считаете?
J>в профайлере или в sysinfo?

с помощью утилиты Process Explorer (www.sysinternals.com) также как и в Task Manager только удобнее
... << Rsdn@Home 1.1.4 beta 1 >>
Re[2]: CoInitialize, CoCreateInstance и потоки
От: Vorobiev Sergei Россия  
Дата: 09.07.04 12:37
Оценка:
Здравствуйте, VictorProg, Вы писали:

VP>Здравствуйте, Vorobiev Sergei, Вы писали:


VS>>Привет, Всем!


VS>>Как полностью освободить ресурсы после того как COM-объект больше не нужен? В приведенном примере память после завершения работы функции потока не освобождается. Если убрать вызов CoCreateInstance, то все нормально. COM-объект ничего не делает — заготовка сгенерированная CB6. Тестовая программа тоже на CB6.


VP>День добрый. Я так думаю, что Release метод должен полностью очистить ресурсы, убрать все ссылки на объект и выполнить ему delete. Попробуй использовать CoInitializeEx(NULL, COINIT_MULTITHREADED), это расширенный вариант, специально для мультитредных задач. Должно помочь.


Пробовал уже не помогает. Я думаю, что дело в повторных вызовах CoInitialize. Как я писал ниже, если я делаю одни вызов CoInitialize, а в цикле создаю и удаляю объект то память растет один раз. Если написать что-то наподобие этого

  for (int i = 0; i < 100; i++)
  {
    CoInitialize(NULL);
    CoUninitialize();
  }


то память не растет.
... << Rsdn@Home 1.1.4 beta 1 >>
Re[3]: CoInitialize, CoCreateInstance и потоки
От: VictorProg  
Дата: 09.07.04 12:46
Оценка:
Здравствуйте, Vorobiev Sergei, Вы писали:

VS>Здравствуйте, VictorProg, Вы писали:


VP>>Здравствуйте, Vorobiev Sergei, Вы писали:


VS>>>Привет, Всем!


VS>>>Как полностью освободить ресурсы после того как COM-объект больше не нужен? В приведенном примере память после завершения работы функции потока не освобождается. Если убрать вызов CoCreateInstance, то все нормально. COM-объект ничего не делает — заготовка сгенерированная CB6. Тестовая программа тоже на CB6.


VP>>День добрый. Я так думаю, что Release метод должен полностью очистить ресурсы, убрать все ссылки на объект и выполнить ему delete. Попробуй использовать CoInitializeEx(NULL, COINIT_MULTITHREADED), это расширенный вариант, специально для мультитредных задач. Должно помочь.


VS>Пробовал уже не помогает. Я думаю, что дело в повторных вызовах CoInitialize. Как я писал ниже, если я делаю одни вызов CoInitialize, а в цикле создаю и удаляю объект то память растет один раз. Если написать что-то наподобие этого


VS>
VS>  for (int i = 0; i < 100; i++)
VS>  {
VS>    CoInitialize(NULL);
VS>    CoUninitialize();
VS>  }
VS>


VS>то память не растет.


Странно, у меня используется CoInitializeEx(NULL, COINIT_MULTITHREADED) и всё работает нормально. Попробуй поменять флаги.
Re[4]: CoInitialize, CoCreateInstance и потоки
От: Vorobiev Sergei Россия  
Дата: 09.07.04 13:13
Оценка:
Здравствуйте, VictorProg, Вы писали:

VP>Здравствуйте, Vorobiev Sergei, Вы писали:


VS>>Здравствуйте, VictorProg, Вы писали:


VP>>>Здравствуйте, Vorobiev Sergei, Вы писали:


VS>>>>Привет, Всем!


VS>>>>Как полностью освободить ресурсы после того как COM-объект больше не нужен? В приведенном примере память после завершения работы функции потока не освобождается. Если убрать вызов CoCreateInstance, то все нормально. COM-объект ничего не делает — заготовка сгенерированная CB6. Тестовая программа тоже на CB6.


VP>>>День добрый. Я так думаю, что Release метод должен полностью очистить ресурсы, убрать все ссылки на объект и выполнить ему delete. Попробуй использовать CoInitializeEx(NULL, COINIT_MULTITHREADED), это расширенный вариант, специально для мультитредных задач. Должно помочь.


VS>>Пробовал уже не помогает. Я думаю, что дело в повторных вызовах CoInitialize. Как я писал ниже, если я делаю одни вызов CoInitialize, а в цикле создаю и удаляю объект то память растет один раз. Если написать что-то наподобие этого


VS>>
VS>>  for (int i = 0; i < 100; i++)
VS>>  {
VS>>    CoInitialize(NULL);
VS>>    CoUninitialize();
VS>>  }
VS>>


VS>>то память не растет.


VP>Странно, у меня используется CoInitializeEx(NULL, COINIT_MULTITHREADED) и всё работает нормально. Попробуй поменять флаги.


Что вы имеете ввиду под нормально? У меня тоже все работает и раньше работало — растет память. Здесь дело не в потоке. Тоже самое будет если поток не создавать.

Можно конечно создавать поток один раз и останавливать его когда это нужно, например,

while(1)
{ 
  WaitForSingleObject(hEvent, INFINITE);
    
    // Делаем то что на надо
}


Но я думаю, что если поток создается редко, то его лучше удалить — зачем ему в памяти висеть... а получается что так только памяти больше отжирается
... << Rsdn@Home 1.1.4 beta 1 >>
Re: CoInitialize, CoCreateInstance и потоки
От: George Seryakov Россия  
Дата: 10.07.04 15:02
Оценка:
Здравствуйте, Vorobiev Sergei, Вы писали:

VS>Как полностью освободить ресурсы после того как COM-объект больше не нужен? В приведенном примере память после завершения работы функции потока не освобождается. Если убрать вызов CoCreateInstance, то все нормально. COM-объект ничего не делает — заготовка сгенерированная CB6. Тестовая программа тоже на CB6.


CB6 — это билдер? Под студией практически с таким же кодом (создаваемый объект другой) проблем не возникает.

В коде странноватым местом является глобальный pObject. Я бы попробовал его убрать в функцию потока.
GS
Re[2]: CoInitialize, CoCreateInstance и потоки
От: Vorobiev Sergei Россия  
Дата: 10.07.04 20:55
Оценка:
Здравствуйте, George Seryakov, Вы писали:

GS>Здравствуйте, Vorobiev Sergei, Вы писали:


VS>>Как полностью освободить ресурсы после того как COM-объект больше не нужен? В приведенном примере память после завершения работы функции потока не освобождается. Если убрать вызов CoCreateInstance, то все нормально. COM-объект ничего не делает — заготовка сгенерированная CB6. Тестовая программа тоже на CB6.


GS> CB6 — это билдер? Под студией практически с таким же кодом (создаваемый объект другой) проблем не возникает.


Да. Под студией создал точно такой же пример и действительно все нормально. Странно, возможно под билдером в коде, который создает визард что-то не так.

GS> В коде странноватым местом является глобальный pObject. Я бы попробовал его убрать в функцию потока.


Да. Так будет логичнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.