Dynamic created objects are not released within QML's Column!
-
Hi all,
I'm using Qt 5.9.7 on Windows. And I tested it with Qt 5.12.2: same issue!
During runtime I want to fill a Column with dynamic created items.
This is done with setting the parent of the created item to Column.I hold the items in an JS array to have access later e.g. setting values, texts.
But when I want to clear (make empty) the Column it seems the memory is not given free.Now the situation is that the Column is very often filled and cleared during runtime which later leads to an application crash because "out of memory".
I have verfied this by observing memory with task manager.
Is that bug or is my code wrong?
Using a repeater is not parctical because the dynamic created items are very complex and would blast implementing them by a delegate.Here is a short example to test it, press key "1" to add item, "2" for delete all, "T" to start filling/deleting automatically to see better changes in task manager:
import QtQuick 2.4 Rectangle { width: 480 height: 320 color: "gray" clip: true property var items: [] // adds an item to column // function addItem() { var item = component.createObject(column) items.push(item) text.text = "Count of items: " + items.length } // deletes all items of column // function deleteAllItems() { for (var i = 0; i < items.length; i++) { items[i].parent = null items[i].destroy() items[i] = null } items.length = 0 text.text = "Count of items: " + items.length } Column { id: column spacing: 1 } // shows only the number of columns items // Text { id: text anchors.left: column.right } // used for fast insert of items to column // Timer { id: timer interval: 100 repeat: true onTriggered: { // more than 50 items ? then we delete all! // if (items.length > 50) { deleteAllItems() } else { addItem() } } } // some key for testing // focus: true Keys.onPressed: { if (event.key === Qt.Key_1) { addItem() } else if (event.key === Qt.Key_2) { deleteAllItems() } else if (event.key === Qt.Key_T) { if (timer.running) timer.stop() else timer.start() } event.accepted = true } // columns item // Component { id: component Rectangle { id: rect width: 120 height: 50 color: "red" // need some space. better to see in taskmanager! // property string text1: "kjdkfdjkjfksdfsdkfsdkfdsjf" property string text2: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" property string text3: "bbbbbbbbbbbbbbbb" property string text4: "llllllllllllllllllllllllllllllllllllllllllll" Text { text: "index " + rect.Positioner.index } } } }
THX
-
Cannot reproduce:
import QtQuick 2.4 import QtQuick.Window 2.2 Window { visible: true width: 640 height: 480 title: qsTr("Hello World") property var items: [] // adds an item to column // function addItem() { var item = component.createObject(column) items.push(item) text.text = "Count of items: " + items.length } // deletes all items of column // function deleteAllItems() { for (var i = 0; i < items.length; i++) { items[i].parent = null items[i].destroy() items[i] = null } items.length = 0 text.text = "Count of items: " + items.length } //import QtQuick 2.4 Rectangle { width: 480 height: 320 color: "gray" clip: true Column { id: column spacing: 1 } // shows only the number of columns items // Text { id: text anchors.left: column.right } // used for fast insert of items to column // Timer { id: timer interval: 1 // 100 repeat: true onTriggered: { // more than 50 items ? then we delete all! // if (items.length > 1000) {//50) { deleteAllItems() } else { addItem() } } } // some key for testing // focus: true Keys.onPressed: { if (event.key === Qt.Key_1) { addItem() } else if (event.key === Qt.Key_2) { deleteAllItems() } else if (event.key === Qt.Key_T) { if (timer.running) timer.stop() else timer.start() } event.accepted = true } // columns item // Component { id: component Rectangle { id: rect width: 120 height: 50 color: "red" // need some space. better to see in taskmanager! // property string text1: "kjdkfdjkjfksdfsdkfsdkfdsjf" property string text2: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" property string text3: "bbbbbbbbbbbbbbbb" property string text4: "llllllllllllllllllllllllllllllllllllllllllll" Text { text: "index " + rect.Positioner.index } } } } }
main.c:
#include <QGuiApplication> #include <QQmlApplicationEngine> int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QQmlApplicationEngine engine; engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); if (engine.rootObjects().isEmpty()) return -1; return app.exec(); }
I do not get runaway memory allocation occuring. It actually seems very low memory allocation.
I am running:
Ubuntu Linux 18.04
Qt 5.12.2
Mingw 7.3 64 bit
Monitored memory with top command -
Hhhm...
the code was only a simple snipped. The original code where the issue occurs is more complex, import scripts, uses inheritance, access C++ objects.
The posted example was very small and tight.
Now I have prepared a better example, consists of serveral files (qml, js). It's similar to original code structure. When I start this example at beginning the memory usage rises fast and much space. After short while its rises slower and less space... but rises continually.
I have tested it with Qt's qmlscene.exe.
Note:
I have tested also on Win10, with Qt 5.4.1, no memory issue!
Strange