2017-04-08 2 views
-2

Ich habe einige WMI Speicherleck Problem beim Sprachenwechsel. Ich habe es in Task Manager überprüft. Zum Beispiel dauert meine App 25 MB RAM, wenn Sprachen geändert werden, wächst es auf 30 MB und 35, 40 ... und veröffentlicht es nie.WMI-Speicherleck Problem

//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 

Wie behebt man dieses Problem? Danke im Voraus.

Test Screenshot, wo ich über Speicherleck überprüft haben:

Code:

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

Keine der Spalten in den Task-Manager zeigen die Menge an RAM ein Prozess einnimmt. Welchen Wert schaust du wirklich? Und warum gehen Sie davon aus, dass es ein Speicherleck gibt? Stellen Sie sicher, dass Sie [Speicherverwaltung] verstehen (https://msdn.microsoft.com/en-us/library/windows/desktop/aa366525.aspx). – IInspectable

+0

Wenn Sie einen Screenshot hochladen müssen, setzen Sie ihn in Ihre Frage. Und verwenden Sie einen unterstützten Image-Host. * fastpic.ru * ist kein unterstützter Image-Host. – IInspectable

+0

Meine App braucht Speicher und gibt sie niemals frei, sollte ich das also als kein Leck betrachten? – Cobra91151

Antwort

0

@IInspectable

Danke. Ich habe das Speicherleckproblem WMI behoben, indem ich Ressourcen freigegeben habe.

Code:

... 
      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. 
}