Memory leak using QThread issue
-
Hi! I have made a changelog feature to my application. I have created worker class and connect all signals and slots with
QThread
. The problem is when I start a thread to update data more then one time it begin to leak RAM memory.Code:
appCheckUpdate = new CheckUpdates(); appCheckUpdatesThread = new QThread(); appCheckUpdate->moveToThread(appCheckUpdatesThread); connect(appCheckUpdatesThread, &QThread::started, appCheckUpdate, &CheckUpdates::checkUpdate); connect(appCheckUpdate, &CheckUpdates::updateData, this, &Changelog::getUpdateData); connect(appCheckUpdate, &CheckUpdates::networkError, this, &Changelog::changeLogUpdateError); connect(appCheckUpdate, &CheckUpdates::localeError, this, &Changelog::updateLocaleError); connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit, Qt::DirectConnection); appCheckUpdatesThread->start();
When I create this on the stack:
appCheckUpdate.moveToThread(&appCheckUpdatesThread); connect(&appCheckUpdatesThread, &QThread::started, &appCheckUpdate, &CheckUpdates::checkUpdate); connect(&appCheckUpdate, &CheckUpdates::updateData, this, &Changelog::getUpdateData); connect(&appCheckUpdate, &CheckUpdates::networkError, this, &Changelog::changeLogUpdateError); connect(&appCheckUpdate, &CheckUpdates::localeError, this, &Changelog::updateLocaleError); connect(&appCheckUpdate, &CheckUpdates::finished, &appCheckUpdatesThread, &QThread::quit, Qt::DirectConnection); appCheckUpdatesThread.start();
It duplicates data and also leak is still present. How to fix this issue? Thanks in advance.
-
Hi,
In the first case, you don't seem to delete
appCheckUpdate
norappCheckUpdateThread
.As for the leak, how do you know you are leaking something ?
Are you properly handling all resource in your custom classes ?
-
I have checked the memory leak by Task Manager.
I have some questions:
- Qt does not delete objects when use
connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit, Qt::DirectConnection);
?
I thought when thread has been deleted than the object
appCheckUpdate
should be also deleted or not?- So where do I have to delete those objects (in destructor)?
Thanks in advance for your help.
- Qt does not delete objects when use
-
A thread calling finished doesn't delete itself like that, it's your job to know when it should be deleted. If it's when
CheckUpdates::finished
then connect thedeleteLater
function to it. -
@Cobra91151 as an additional note,
Using
Qt::DirectConnection
instead ofQt::QueuedConnection
is asking for trouble!
Signal/Slot Connections are threadsave because they are automatically queued, accpet if you give it Qt::DirectConnection as a 5th parameter. -
I use
connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::deleteLater);
but then I get warning:QThread: Destroyed while thread is still running
.So should I connection like this:
connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit); connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater);
Or it will not work because the thread is not destroyed?
-
@Cobra91151 said in Memory leak using QThread issue:
So should I connection like this:
connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit); connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater);
Or it will not work because the thread is not destroyed?
No, this is exactly the correct way to do it.
-
I have changed code to:
appCheckUpdate = new CheckUpdates(); appCheckUpdatesThread = new QThread(); appCheckUpdate->moveToThread(appCheckUpdatesThread); connect(appCheckUpdatesThread, &QThread::started, appCheckUpdate, &CheckUpdates::checkUpdate); connect(appCheckUpdate, &CheckUpdates::updateData, this, &Changelog::getUpdateData); connect(appCheckUpdate, &CheckUpdates::networkError, this, &Changelog::changeLogUpdateError); connect(appCheckUpdate, &CheckUpdates::localeError, this, &Changelog::updateLocaleError); connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit); connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater); appCheckUpdatesThread->start();
But the problem still exists, it leaks memory. So this -
connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater);
- deletes onlyappCheckUpdatesThread
(QThread
) object.So should I also delete
appCheckUpdate
by callingdelete appCheckUpdate
? -
@Cobra91151
yes of course,
at the end of your threaded operation, you'll have to delete your QThread object and your Worker object, seperately.In case you haven't seen it, heres an wiki-example
-
@Cobra91151 It should be:
connect(appCheckUpdatesThread, &QThread::finished, appCheckUpdatesThread, &QThread::deleteLater);
In http://doc.qt.io/qt-5.8/qthread.html#finished
"This signal can be connected to QObject::deleteLater(), to free objects in that thread." -
Hi! I have some WMI memory leak issue.
Code:
//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
Every time I change language in my app it takes 1 - 5 MB RAM. How to fix this issue? Thanks in advance.
-
@Cobra91151 This isn't Qt code.. You should probably post this question on a win32 API message board.
Also are you sure it's actually leaking? Just because the size of memory for your running application grows does not mean it's leaking. You need something like valgrind to test for leaks on exit.
-
I have checked it in Task Manager. For example, my app takes 25 MB RAM, when changing languages it grows to 30 MB and 35, 40... and never release it. So should I consider this as not a leak?
-
What do you mean by changing languages ? What do you do to make that happen ?
-
I have all
WMI
data inQTreeWidgetItems
(QTreeWidget
). I have two columns:
1 - Property
2 - DataProperty and data I get from a
worker
class which connected with signals and slots to thread. So to change property to another language I callclear
function onQTreeWidget
to delete all property and data, then I call function which connects worker to thread and get this data asQTreeWidgetItems
in chosen (translated) language. -
Are you loading any language file in order to provide translations ?
-
Yes, but when
QComboBox
index changes I call this function to load appropriate translation file:Some code:
appTranslator = new QTranslator(this); qApp->removeTranslator(appTranslator); appTranslator->load(":Localization/Test_ru.qm"); qApp->installTranslator(appTranslator);
and when apply button is clicked I retranslate string and reload
WMI
data using myloadTraslatedText
function