Memory Leak Caused by Frequent Dynamic Creation/Destruction of QML Windows in Qt 5.15.19 on Windows
-
Hello everyone,
I am encountering a significant memory leak when repeatedly creating and destroying
Windowcomponents (using QML) in a Qt 5.15.19 application on Windows. The issue appears to be related to unreleased shared resources. I would greatly appreciate any help or insight you can provide.
Environment for Reproduction
- OS: Windows 10 (running in a VMware virtual machine)
- Qt Version: 5.15.19
- Application Type: Qt Quick (QML)
- Compiler/Architecture: The test program is compiled as a 32-bit application. (MSVC 2022, 32-bit)
Minimal Reproducible Test Code
The issue can be observed by running the following two QML files. The
Timerinmain.qmlcontinuously creates and destroys a newSessionWininstance every second.main.qmlimport QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.12 Window { id: id_main_win visible: true width: 1280 height: 720 color: "blue" property int createCount: 0 Text { anchors.centerIn: parent text: createCount font.pixelSize: 30 } Button { id: top_right_button width: 200 height: 40 font.pixelSize: 16 text: "stop" anchors { top: parent.top right: parent.right } onClicked: { console.info(`stop createSession timer, createCount ${createCount}`) id_timer.stop() if (id_timer.tmpwin) { id_timer.tmpwin.destroy() id_timer.tmpwin = null } } background: Rectangle { color: top_right_button.hovered ? "#e0e0e0" : "red" radius: 5 } } Button { id: top_left_button width: 200 height: 40 font.pixelSize: 16 text: "restart" anchors { top: parent.top left: parent.left } onClicked: { console.info("restart createSession timer") id_timer.restart() } background: Rectangle { color: top_left_button.hovered ? "#e0e0e0" : "red" radius: 5 } } Timer { id: id_timer repeat: true interval: 1000 // Creates and destroys a window every second property var tmpwin: null onTriggered: { if (tmpwin) { tmpwin.destroy() tmpwin = null } tmpwin = createSession() } } Component { id: id_sess SessionWin { } } function createSession() { var win = id_sess.createObject(id_main_win) createCount += 1 return win } }SessionWin.qmlimport QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.12 Window { id: id_session_win width: 1024 height: 1024 visible: true Component.onCompleted: { console.debug(`memoryTracer: create object: ${this}, size: ${width}x${height}`) } Component.onDestruction: { console.debug(`memoryTracer: destroy object: ${this}`) } }Preliminary Analysis Findings
- Shared Memory Accumulation: The process's shared memory usage continuously increases over time.
- Using the vmmap.exe tool to examine the process's virtual address space, I found that each creation/destruction cycle leaves behind a shared memory block of approximately 4320 KB.
- For instance, if I repeat the create/destroy cycle 80 times, there will be 80 unreleased shared memory blocks of 4320 KB each.
- Shared GPU Resource: When the test program is run on a physical machine (instead of a VM), the leaked memory region is identified as being related to Shared GPU resources. This suggests an unreleased graphics/window resource.
I suspect this may be a bug related to how Qt 5.15.19 handles the cleanup of platform-specific resources (possibly related to the windowing system or graphics backend) when a QML
Windowis dynamically destroyed.Has anyone else experienced this specific behavior, especially when using dynamic QML window creation/destruction? Do you know of any workarounds or configuration settings that might mitigate this leak?
Thank you for your time and expertise!
-
Hello everyone,
I am encountering a significant memory leak when repeatedly creating and destroying
Windowcomponents (using QML) in a Qt 5.15.19 application on Windows. The issue appears to be related to unreleased shared resources. I would greatly appreciate any help or insight you can provide.
Environment for Reproduction
- OS: Windows 10 (running in a VMware virtual machine)
- Qt Version: 5.15.19
- Application Type: Qt Quick (QML)
- Compiler/Architecture: The test program is compiled as a 32-bit application. (MSVC 2022, 32-bit)
Minimal Reproducible Test Code
The issue can be observed by running the following two QML files. The
Timerinmain.qmlcontinuously creates and destroys a newSessionWininstance every second.main.qmlimport QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.12 Window { id: id_main_win visible: true width: 1280 height: 720 color: "blue" property int createCount: 0 Text { anchors.centerIn: parent text: createCount font.pixelSize: 30 } Button { id: top_right_button width: 200 height: 40 font.pixelSize: 16 text: "stop" anchors { top: parent.top right: parent.right } onClicked: { console.info(`stop createSession timer, createCount ${createCount}`) id_timer.stop() if (id_timer.tmpwin) { id_timer.tmpwin.destroy() id_timer.tmpwin = null } } background: Rectangle { color: top_right_button.hovered ? "#e0e0e0" : "red" radius: 5 } } Button { id: top_left_button width: 200 height: 40 font.pixelSize: 16 text: "restart" anchors { top: parent.top left: parent.left } onClicked: { console.info("restart createSession timer") id_timer.restart() } background: Rectangle { color: top_left_button.hovered ? "#e0e0e0" : "red" radius: 5 } } Timer { id: id_timer repeat: true interval: 1000 // Creates and destroys a window every second property var tmpwin: null onTriggered: { if (tmpwin) { tmpwin.destroy() tmpwin = null } tmpwin = createSession() } } Component { id: id_sess SessionWin { } } function createSession() { var win = id_sess.createObject(id_main_win) createCount += 1 return win } }SessionWin.qmlimport QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.12 Window { id: id_session_win width: 1024 height: 1024 visible: true Component.onCompleted: { console.debug(`memoryTracer: create object: ${this}, size: ${width}x${height}`) } Component.onDestruction: { console.debug(`memoryTracer: destroy object: ${this}`) } }Preliminary Analysis Findings
- Shared Memory Accumulation: The process's shared memory usage continuously increases over time.
- Using the vmmap.exe tool to examine the process's virtual address space, I found that each creation/destruction cycle leaves behind a shared memory block of approximately 4320 KB.
- For instance, if I repeat the create/destroy cycle 80 times, there will be 80 unreleased shared memory blocks of 4320 KB each.
- Shared GPU Resource: When the test program is run on a physical machine (instead of a VM), the leaked memory region is identified as being related to Shared GPU resources. This suggests an unreleased graphics/window resource.
I suspect this may be a bug related to how Qt 5.15.19 handles the cleanup of platform-specific resources (possibly related to the windowing system or graphics backend) when a QML
Windowis dynamically destroyed.Has anyone else experienced this specific behavior, especially when using dynamic QML window creation/destruction? Do you know of any workarounds or configuration settings that might mitigate this leak?
Thank you for your time and expertise!
Hi @jason1122, and welcome!
Do you still see the memory leak with Qt 6.10.0?