WMI内存泄漏问题

WMI memory leak issue

我在更改语言时遇到一些 WMI 内存泄漏问题。我已经在 Task Manager 中查看过了。例如,我的应用程序需要 25 MB RAM,当更改语言时它会增长到 30 MB 和 35、40... 并且永远不会发布它。

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

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