Memory leaks in Qt app
-
Hi! I have checked my app with Visual Leak Detector and it has found more than 2000 memory leaks.
Visual Leak Detector detected 2106 memory leaks (237576 bytes).
Largest number used: 238113 bytes.
Total allocations: 241457 bytes.How to fix these issues?
-
Hi! Are these leaks in your code or in code from the Qt framework?
-
@Wieland
Some in my code and some in qt:
VLD output:Qt5Cored.dll!QPauseAnimation::duration() + 0x44B42D bytes Qt5Cored.dll!QPauseAnimation::duration() + 0x456349 bytes Qt5Cored.dll!QPauseAnimation::duration() + 0x44CC79 bytes Qt5Cored.dll!QPauseAnimation::duration() + 0x505C71 bytes qwindowsd.dll!qt_plugin_instance() + 0xD7661 bytes Qt5Cored.dll!QPauseAnimation::duration() + 0x503988 bytes USER32.dll!CallWindowProcW() + 0x4F4 bytes USER32.dll!DispatchMessageW() + 0x1BC bytes Qt5Cored.dll!QPauseAnimation::duration() + 0x504392 bytes qwindowsd.dll!qt_plugin_instance() + 0xD7621 bytes Qt5Cored.dll!QPauseAnimation::duration() + 0x44607F bytes Qt5Cored.dll!QPauseAnimation::duration() + 0x4462C5 bytes Qt5Cored.dll!QPauseAnimation::duration() + 0x449196 bytes Qt5Guid.dll!QOpenGLFunctions_1_1::glVertex2iv() + 0x99E9D bytes
-
I'd say fix your bugs first and then look for known issues / report issues at https://bugreports.qt.io.
-
@Wieland
Ok. But how to fix this:
c:\..\..\qt projects\test\main.cpp (16): Test.exe!main() + 0x6 bytes
On 16 line is
return app.exec();
function? -
You need to check the body of your main() function for heap allocations / non-deleted objects. If you like, post it here, so we can try to find the problem together.
-
@Wieland
ManageStartup *appWindow = new ManageStartup(); appWindow->setParent(nullptr); return app.exec();
ManageStartup - QObject class, in this class I check some data before displaying the main GUI window.
Also I have noticed that Qt 5.7.1 in debug mode when debugging app takes more memory than in release. In Qt 5.7.0 memory management was the same in debug and release modes.
-
And that's a bug. You allocate
appWindow
on the heap. As it is aQObject
, you could do the following:appWindow->setParent(&app);
In this case, once
app
gets destroyed (when control leavesmain
),app
would automatically delete its child `` appWindow```.But right now,
appWindow
has no QObject-parent, so you have to delete it by yourself.Or just make it a stack object:
ManageStartup appWindow;
-
@Wieland
Thanks. I have changed code to:
ManageStartup appWindow; appWindow.setParent(&app); return app.exec();
and check for memory leaks again, but the leak is still in main.cpp (16): Test.exe!main() + 0x6 bytes,
return app.exec();
Main.cpp:
#include <QApplication> #include <vld.h> #include "managestartup.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); QThread::currentThread()->setPriority(QThread::HighestPriority); QSharedMemory sharedMemory(APP_NAME); app.setApplicationVersion(APP_VERSION); if (sharedMemory.create(1) && sharedMemory.error() != QSharedMemory::AlreadyExists) { ManageStartup appWindow; appWindow.setParent(&app); return app.exec(); } else { int userRespond = QMessageBox::warning(nullptr, QObject::tr("Test"), QObject::tr("Another instance?"), QMessageBox::Yes | QMessageBox::No); if (userRespond == QMessageBox::Yes) { ManageStartup appWindow; appWindow.setParent(&app); return app.exec(); } } }
-
That looks good to me so far. Now follow the call stack in the VLD log. I guess the next leak is in ManageStartup.
-
@Wieland
Ok. I will check it. Thanks.
-
@Wieland
Hi! I have fixed some memory leaks by changing objects from heap memory allocation to stack but some leaks still exists.
c:..\qt projects\test\test.cpp (2885): Test.exe!Test::event()
bool Test::event(QEvent *event) { if (event->type() == QEvent::WindowStateChange) { appSettings.beginGroup("AppSettings"); if (this->isMinimized() && appSettings.allKeys().contains("minimizeToTray") && appSettings.value("minimizeToTray") == true) { setNotifyIcon(); showNotification(); this->hide(); } appSettings.endGroup(); } return QWidget::event(event); }
On line 2885 is
}
so I think something withreturn QWidget::event(event)
? Thanks in advance. -
The reported potential leak regarding
event
is a false positive, just ignore it. VLD simply isn't smart enough to understand what's going on.See also QCoreApplication Class:
the post event queue will take ownership of the event and delete it once it has been posted
-
@Wieland
Ok. Thanks.
-
My app gets WMI data and displays it as
QTreeWidgetItem
, but it consumes to muchRAM
memory when changing languages.void MyApp::appOSThread() { try { osWorker = new Worker(); osThread = new QThread(osWorker); osWorker->moveToThread(osThread); connect(osThread, &QThread::started, osWorker, &Worker::appOSWMIData); connect(osWorker, &Worker::appOSData, this, &MyApp::osWMIData); connect(osWorker, &Worker::hardwareDataNotAvailable, this, &MyApp::osWMIDataNotAvailable); connect(osWorker, &Worker::errorNotSupportedOS, this, &MyApp::appNotSupportedOS); connect(osWorker, &Worker::finished, osThread, &QThread::quit, Qt::DirectConnection); connect(osThread, &QThread::destroyed, osThread, &QThread::deleteLater); osThread->start(); logData(QObject::tr("Application: gets OS information")); } catch (...) { QMessageBox::critical(this, QObject::tr("Error"), QObject::tr("An error has occurred with detecting OS!")); } } void MyApp::osWMIData(QStringList property, QStringList data) { int countOSProperties = property.count(); QString osProperty; QString osData; for (int i = 0; i < countOSProperties; i++) { osProperty = property.at(i); osData = data.at(i); osItem = new QTreeWidgetItem(osView); //osView - QTreeWidget osItem->setText(0, osProperty); osItem->setText(1, osData); } } void MyApp::appLocalization() { osView->clear(); appOSThread(); }
For example when app is started takes 30 MB when change language then it takes 3 - 5 MB RAM and when changing again it takes again 5 - 10 MB of RAM.
Any ideas?