Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-50319

QML garbage collection deletes objects still in use

    XMLWordPrintable

Details

    Description

      The QML engine appears to have a bug in object lifetime management. According to the documentation, an object will not be collected if it either has a parent or is referenced by the JS engine.

      Yet in the following example, objects are deleted while still matching those two requirements. Objects are properly parented and referenced by JS code when they get deleted:

      / ObjMain.qml
      Item {
          property ListModel list : ListModel { }
          Component.onCompleted: console.log("created " + this + " with parent " + parent)
          Component.onDestruction: console.log("deleted " + this)
      }
      
      // Uimain.qml
      Item {
          id: main
          width: childrenRect.width
          height: childrenRect.height
          property Item object
          property bool expanded : true
          Loader {
              id: li
              x: 50
              y: 50
              active: expanded && object && object.list.count
              width: childrenRect.width
              height: childrenRect.height
              sourceComponent: listView
          }
          Component {
              id: listView
              ListView {
                  width: contentItem.childrenRect.width
                  height: contentItem.childrenRect.height
                  model: object.list
                  delegate: Item {
                      id: p
                      width: childrenRect.width
                      height: childrenRect.height
                      Component.onCompleted: Qt.createComponent("Uimain.qml").createObject(p, {"object" : o})
                  }
              }
          }
          Rectangle {
              width: 50
              height: 50
              color: "red"
      
              MouseArea {
                  anchors.fill: parent
                  acceptedButtons: Qt.RightButton | Qt.LeftButton
                  onClicked: {
                      if (mouse.button == Qt.RightButton) {
                          expanded = !expanded
                      } else {
                          object.list.append({ "o" : Qt.createComponent("ObjMain.qml").createObject(object) })
                      }
                  }
              }
          }
      }
      
      // main.qml
      
      Window {
          visible: true
          width: 1280
          height: 720
      
          ObjMain {
              id: obj
          }
      
          Uimain {
              object: obj
          }
      }
      

      The example is a trivial object tree builder, with the left button adding a leaf to the node and the right button collapsing the node. All it takes to reproduce the bug is to create a node with depth of 3 and then collapse and expand the root node, upon which the console output shows:

      qml: created ObjMain_QMLTYPE_0(0x1e15bb8) with parent QQuickRootItem(0x1e15ca8)
      qml: created ObjMain_QMLTYPE_0(0x1e5afc8) with parent ObjMain_QMLTYPE_0(0x1e15bb8)
      qml: created ObjMain_QMLTYPE_0(0x1e30f58) with parent ObjMain_QMLTYPE_0(0x1e5afc8)
      qml: deleted ObjMain_QMLTYPE_0(0x1e30f58)
      

      This is just one of the several cases I experienced arbitrary object deletions, such happen to both objects, returned from C++ and objects, created entirely in QML. In this particular case the deletion seems to be connected to where createObject() is being called - if instead in the UI the objects is created in a function in main.qml, which is called in the UI then the deletion does not take place. However, I wasn't able to pinpoint any such dependencies in the other cases of arbitrary object deletion.

      Attachments

        For Gerrit Dashboard: QTBUG-50319
        # Subject Branch Project Status CR V

        Activity

          People

            shausman Simon Hausmann
            utcenter Dian Obreshkov
            Votes:
            15 Vote for this issue
            Watchers:
            25 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes