2017-04-08 207 views
-2

更改语言时,我有一些WMI内存泄漏问题。我已在Task Manager中检查过它。例如,我的应用需要25 MB的RAM,当改变语言时,它增长到30 MB和35,40 ...并且从不释放它。WMI内存泄漏问题

//Initialization 
IWbemLocator *pLocator = 0; 
IWbemServices *pService = 0; 
IEnumWbemClassObject* pEnumerator = NULL; 
IWbemClassObject *pclsObj = NULL; 

while (pEnumerator) 
{ 
     hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); 

     VARIANT processName; 
     pclsObj->Get(L"Name", 0, &processName, 0, 0); 
     QString userProcessName; 
     userProcessName = QString::fromWCharArray(processName.bstrVal); 

     emit testData(userProcessName); 
     VariantClear(&processName); 
} 

//Cleanup 
pService->Release(); 
pLocator->Release(); 
//pEnumerator->Release(); - Clang Static Analyzer displays issue - called C++ object pointer is null 
//pclsObj->Release(); - Clang Static Analyzer displays issue - called C++ object pointer is null 

如何解决此问题?提前致谢。这里,我查了一下内存泄漏

测试截图:

代码:

int Test::allServicesWMIData() 
{ 
    HRESULT hres; 

    // Initialize COM. 
    hres = CoInitializeEx(0, COINIT_APARTMENTTHREADED); 

    if (FAILED(hres)) 
    { 
     emit initComLibError(QString(QObject::tr("Failed to initialize COM library. Error code =") + " 0x%1").arg(hexErrorData(hres))); 
     return 1;    // Program has failed. 
    } 

    IWbemLocator *pLocator = 0; 

    hres = CoCreateInstance(
     CLSID_WbemLocator, 
     0, 
     CLSCTX_INPROC_SERVER, 
     IID_IWbemLocator, (LPVOID *)&pLocator); 

    if (FAILED(hres)) 
    { 
     emit errorCreateIWbemObject(QString(QObject::tr("Failed to create IWbemLocator object. Error code =") + " 0x%1").arg(hexErrorData(hres))); 
     CoUninitialize(); 
     return 1;  // Program has failed. 
    } 

    IWbemServices *pService = 0; 

    hres = pLocator->ConnectServer(
     _bstr_t(L"ROOT\\CIMV2"), // WMI namespace 
     NULL,     // User name 
     NULL,     // User password 
     0,      // Locale 
     NULL,     // Security flags 
     0,      // Authority 
     0,      // Context object 
     &pService     // IWbemServices proxy 
    ); 

    if (FAILED(hres)) 
    { 
     emit errorRootConnection(QString(QObject::tr("Could not connect. Error code =") + " 0x%1").arg(hexErrorData(hres))); 
     pLocator->Release(); 
     CoUninitialize(); 
     return 1;    // Program has failed. 
    } 

    hres = CoSetProxyBlanket(
     pService,       // the proxy to set 
     RPC_C_AUTHN_WINNT,   // authentication service 
     RPC_C_AUTHZ_NONE,    // authorization service 
     NULL,       // Server principal name 
     RPC_C_AUTHN_LEVEL_CALL,  // authentication level 
     RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level 
     NULL,       // client identity 
     EOAC_NONE      // proxy capabilities 
    ); 

    if (FAILED(hres)) 
    { 
     emit errorProxyBlanket(QString(QObject::tr("Could not set proxy blanket. Error code =") + " 0x%1").arg(hexErrorData(hres))); 
     pService->Release(); 
     pLocator->Release(); 
     CoUninitialize(); 
     return 1;    // Program has failed. 
    } 

    IEnumWbemClassObject* pEnumerator = NULL; 
    hres = pService->ExecQuery(
     bstr_t("WQL"), 
     bstr_t("SELECT * FROM Win32_Service"), 
     WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
     NULL, 
     &pEnumerator); 

    IWbemClassObject *pclsObj = NULL; 

    if (FAILED(hres)) 
    { 
     emit errorProcessQuery(QString(QObject::tr("Query for processes failed. Error code =") + " 0x%1").arg(hexErrorData(hres))); 
     pService->Release(); 
     pLocator->Release(); 
     CoUninitialize(); 
     return 1;    // Program has failed. 
    } 
    else 
    { 
     ULONG uReturn = 0; 

     while (pEnumerator) 
     { 
      hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn); 

      VARIANT serviceName; 
      VARIANT servicePath; 
      VARIANT serviceID; 
      VARIANT serviceType; 
      VARIANT serviceState; 
      VARIANT serviceStatus; 
      VARIANT serviceErrorControl; 
      VARIANT serviceStartMode; 
      VARIANT serviceWaitHint; 
      VARIANT serviceExitCode; 

      if (hres != 0) { 
       emit hardwareDataNotAvailable(); 
       break; 
      } else { 
       pclsObj->Get(L"Caption", 0, &serviceName, 0, 0); 
       pclsObj->Get(L"PathName", 0, &servicePath, 0, 0); 
       pclsObj->Get(L"ProcessId", 0, &serviceID, 0, 0); 
       pclsObj->Get(L"ServiceType", 0, &serviceType, 0, 0); 
       pclsObj->Get(L"State", 0, &serviceState, 0, 0); 
       pclsObj->Get(L"Status", 0, &serviceStatus, 0, 0); 
       pclsObj->Get(L"ErrorControl", 0, &serviceErrorControl, 0, 0); 
       pclsObj->Get(L"StartMode", 0, &serviceStartMode, 0, 0); 
       pclsObj->Get(L"WaitHint", 0, &serviceWaitHint, 0, 0); 
       pclsObj->Get(L"ExitCode", 0, &serviceExitCode, 0, 0); 
      } 

      QString userServiceName = QString::fromWCharArray(serviceName.bstrVal); 
      QString userServicePath = QString::fromWCharArray(servicePath.bstrVal); 
      QString userServiceID = QString::number(serviceID.uintVal); 
      QString userServiceType = QString::fromWCharArray(serviceType.bstrVal); 
      QString userServiceState = QString::fromWCharArray(serviceState.bstrVal); 
      QString userServiceStatus = QString::fromWCharArray(serviceStatus.bstrVal); 
      QString userServiceErrorControl = QString::fromWCharArray(serviceErrorControl.bstrVal); 
      QString userServiceStartMode = QString::fromWCharArray(serviceStartMode.bstrVal); 
      QString userServiceWaitHint = QString::number(serviceWaitHint.uintVal); 
      QString userServiceExitCode = QString::number(serviceExitCode.uintVal); 

      emit appAllServicesData(userServiceName, userServicePath, userServiceID, userServiceType, userServiceState, userServiceStatus, userServiceErrorControl, 
      userServiceStartMode, userServiceWaitHint, userServiceExitCode); 

      VariantClear(&serviceName); 
      VariantClear(&servicePath); 
      VariantClear(&serviceID); 
      VariantClear(&serviceType); 
      VariantClear(&serviceState); 
      VariantClear(&serviceStatus); 
      VariantClear(&serviceErrorControl); 
      VariantClear(&serviceStartMode); 
      VariantClear(&serviceWaitHint); 
      VariantClear(&serviceExitCode); 
     } 
    } 

    // Cleanup 
    pService->Release(); 
    pLocator->Release(); 
    //pEnumerator->Release(); - Clang Static Analyzer displays issue - called C++ object pointer is null 
    //pclsObj->Release(); - Clang Static Analyzer displays issue - called C++ object pointer is null 
    CoUninitialize(); 
    emit finished(); 
    return 0; // Program successfully completed. 
} 
+0

在任务管理器中的列中没有显示的RAM的过程会​​占用多少。你真的在看什么价值?你为什么假设存在内存泄漏?确保你了解[内存管理](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366525.aspx)。 – IInspectable

+0

如果你需要张贴截图,把它放在你的问题。并使用支持的图像主机。 * fastpic.ru *不是支持的图像主机。 – IInspectable

+0

我的应用程序需要内存并且永远不会释放它,所以我应该认为这不是泄漏? – Cobra91151

回答

0

@IInspectable

谢谢。我通过释放资源修复了WMI内存泄漏问题。

代码:

... 
      VariantClear(&serviceName); 
      VariantClear(&servicePath); 
      VariantClear(&serviceID); 
      VariantClear(&serviceType); 
      VariantClear(&serviceState); 
      VariantClear(&serviceStatus); 
      VariantClear(&serviceErrorControl); 
      VariantClear(&serviceStartMode); 
      VariantClear(&serviceWaitHint); 
      VariantClear(&serviceExitCode); 
      pclsObj->Release(); 
     } 
    } 

    // Cleanup 
    pService->Release(); 
    pLocator->Release(); 
    pEnumerator->Release(); 
    CoUninitialize(); 
    emit finished(); 
    return 0; // Program successfully completed. 
}