QML and memory leaks
-
Hi,
as I start an application from scratch I took the chance to enable ASAN right from the start to catch memory violations and leaks. My app is using Qt 5.15.5. and it's using QML. So far it doesn't do much and except the notorious libfontconfig leaks everything is clean.
Until I added a DropShadow to one of my rectangles. Now DropShadow is producing quite a lot of memory leaks in QQmlPropertyCache.
Just to give an example:
Direct leak of 192 byte(s) in 1 object(s) allocated from: #0 0x7ff8bea4499f in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10d99f) #1 0x7ff8bd34dffd in QQmlPropertyCache::copy(int) qml/qqmlpropertycache.cpp:256 Indirect leak of 7832 byte(s) in 1 object(s) allocated from: #0 0x7ff8bea44b9f in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10db9f) #1 0x7ff8bd34e5b8 in QStringHash<QPair<int, QQmlPropertyData*> >::reserve(int) ../../include/QtQml/5.15.5/QtQml/private/../../../../../src/qml/qml/ftw/qstringhash_p.h:760 #2 0x7ff8bd34e5b8 in QLinkedStringHash<QPair<int, QQmlPropertyData*> >::linkAndReserve(QLinkedStringHash<QPair<int, QQmlPropertyData*> > const&, int) ../../include/QtQml/5.15.5/QtQml/private/../../../../../src/qml/qml/ftw/qlinkedstringhash_p.h:95 #3 0x7ff8bd34e5b8 in QQmlPropertyCache::copy(int) qml/qqmlpropertycache.cpp:262 ... SUMMARY: AddressSanitizer: 17587 byte(s) leaked in 69 allocation(s).
It's probably very likely that these are static leaks because the app shutdown does not destroy all objects on the heap. But it's still annoying to have such a large list of warnings shadowing the real interesting ones.
I had the same situations with previous Qt apps drowning in endless leaks generated from the Qt libraries. So just my general question:
Is this today's state of Qt? Still leaking on app shutdown? Or do I miss something essential when closing the app?
Right now my code is pretty straight forward like:
int main(int argc, char** argv) { #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); #endif int res = -1; { QGuiApplication app(argc, argv); ApplicationEngine engine; const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect(&engine, &ApplicationEngine::objectCreated, &app, [url](QObject* obj, const QUrl& objUrl) { if (!obj && url == objUrl) { QCoreApplication::exit(-1); } }, Qt::QueuedConnection); engine.load(url); res = app.exec(); } return res; }
And in the ApplicationEngine I do:
ApplicationEngine::ApplicationEngine() { addImportPath(QStringLiteral("qrc:/")); QQmlContext* context = rootContext(); device_manager_ = new DeviceManager(this); qRegisterMetaType<ModelConnections*>("ModelConnections*"); context->setContextProperty("deviceManager", device_manager_); }
I am sure that DeviceManager and ModelConnections are not a problem. It's that single drop shadow that triggers hell. So any advice on how to do it better is highly appreciated. Maybe I miss some calls when closing down the app? Or do I miss initialization?
Cheers
Oliver