Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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


Log in to reply