StackView is cause of Memory leak?
-
I'm creating an app using Stackview.
When I monitored the memory usage of the app while switching pages, I found that the memory usage gradually increased.
So, when I created a simple Staciview test program and verified it, I found that the memory usage gradually increased and was not released.I suspect a memory leak. Is there any solution?
I uses Qt 6.5.2.test method on test program:
main page->click button and move to page1->click button and move to page2->back button (pop)->back button (pop)-> main pagemain.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; const QUrl url(u"qrc:/main.qml"_qs); QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, &app, [url](QObject *obj, const QUrl &objUrl) { if (!obj && url == objUrl) QCoreApplication::exit(-1); }, Qt::QueuedConnection); engine.load(url); return app.exec(); }
main.qml
import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 ApplicationWindow { width: 640 height: 480 visible: true title: qsTr("Hello World") Timer{ interval: 100; running: false; repeat: true onTriggered: { } } StackView { id: stackView width:parent.width*0.98 height:parent.height*0.98 anchors.centerIn: parent focus: true initialItem:buttons onCurrentItemChanged: { console.log("stack depth=",stackView.depth) } } ListModel{ id:menuItems ListElement{ _txt:qsTr("1") _url: "Page1.qml" _accent:false _name:"page1" _type:"btn" } ListElement { _txt:qsTr("2") _url:"Page2.qml" _accent:false _name:"page2" _type:"btn" } } Component{ id:buttons GridView{ id:grid cellWidth:parent.width/3 cellHeight:parent.height/3 model:menuItems delegate: Button{ text:_txt //checkable: name==="conveyormode"?true:false onClicked:{ stackView.push(Qt.resolvedUrl(_url),StackView.Immediate) } } } } }
Page1.qml
import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 Page { Rectangle{ width:100;height:100 Button{ id:bk text:"(1) back" onClicked:stackView.pop(StackView.Immediate); } Button{ text:"to 2" onClicked:stackView.push(Qt.resolvedUrl("Page2.qml"),StackView.Immediate) anchors.left: bk.right } } }
Page2.qml
import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 Page { Rectangle{ width:100;height:100 Button{ text:"(2) back" onClicked:stackView.pop(StackView.Immediate); } } }
-
I have been tested well my app which modified including gc() excluding Glow{}& Qt5Compat.GraphicalEffects.
As a result, it didn't consume much memory.[Conclusion]
StackView is not a cause of memory leak.--in my app:
Glow{} (Qt5Compat.GraphicalEffects) was the cause of memory leak. So I removed them.
Periodically running gc() is effective to reduce memory consumption if user operate continuously. -
@ynatynat As I wrote here https://forum.qt.io/topic/152053/best-practices-of-handling-multiple-forms?_=1699862117332 I doubt there is a memory leak.
-
@jsulm
Thank you for replaying.
You means it's not a memory leak, but memory is increasing due to natural memory management by the OS (not freeing it for reuse), right?
I'm creating an app that will be used in a factory, and I don't have many chances to shut down the app, so I would like to reduce memory consumption as much as possible. How can I achieve this? -
@ynatynat You would need to reserve and release more memory many times to see whether there is really a memory leak. Releasing one window and seeing that the memory is still not released does not automatically mean that there is a memory leak.
-
@ynatynat
You do not necessarily have to shut down the app to get the memory back. Once memory is allocated by a process it is "unlikely" to be returned to the OS until the process ends. However, the hope is that the process will re-use that memory after being freed when the process comes to allocate fresh memory.The true test is more like: keep allocating and freeing memory (allowing it to be properly freed by Qt), see whether total memory allocated to the process "settles down" over time rather than keeping growing indefintely.
-
@jsulm
@JonB
Thank you for replying.I tested the app.
test operation: main-move to page1(push(page1))- move to page2(push(page2))-pop()-pop()-main[Result]
Just open:53.6MB
after 1st operation: 55.7MB
after 20th operation:55.9MB
wait one minute and restart operation.
after 40th opereation 55.9MB
after 60th operation 56.2MBIt seems to keep growing.
-
@ynatynat
Run it 100 times.
OIC, you seem to have run it several times, I think. In any case if you are commenting on a difference between 53/55/56MB this is so small it may not be significant.You might also use a tool like valgrind to examine memory allocation. Whether that tool, or another, has issues (e.g. "false positives") with QML code I do not know.
From time to time people post asking/reporting something similar. It is unlikely there are any "leaks" in Qt code, and the behaviour is what it is.
-
-
@JonB
Thank you for advice.I understood that a change of about a few MB is not a critical memory leak.
As a result of investigating on my app, rather than test app, I also found that when I press a button that uses Glow{} (Qt5Compat.GraphicalEffects), memory consumption increases continuously. I think it seems a critical leak.I also found it is better to use gc() if there is a possibility of continuous operation. document
That's why, I expect that my program will improve by excluding Glow{}, Qt5Compat.GraphicalEffects and add periodically running gc().
Although I have only been able to do a few tests so far, it appears that memory consumption tends to be less likely to increase when these are included.
-
I have been tested well my app which modified including gc() excluding Glow{}& Qt5Compat.GraphicalEffects.
As a result, it didn't consume much memory.[Conclusion]
StackView is not a cause of memory leak.--in my app:
Glow{} (Qt5Compat.GraphicalEffects) was the cause of memory leak. So I removed them.
Periodically running gc() is effective to reduce memory consumption if user operate continuously. -