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.
}
我在更改语言时遇到一些 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.
}