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

memory leak in listview usage (QQuickItemView)

    XMLWordPrintable

Details

    • Linux/Wayland
    • 76188bc34 (6.8.3)

    Description

      I ran the provided test code from the key customer and confirmed that a memory leak occurs when executing the test. The test was performed on version v6.2.2, and the same issue occurs in not only v5.5.18 but also v6.8.2.
      (os: ubuntu24.04, qt version: v6.2.2, v6.8.2, v5.5.18)

      I have attached the heaptrack results from both v6.2.2 and v6.8.2.

      From the heaptrack analysis, I observed that in the "consumed page" section, the memory usage continuously increases at a steady rate due to the connectImpl function.(yellow in below image)

       

       

      Even though the same test code was executed, the "Largest Memory Leaks" section on the "summary page" sometimes shows results and sometimes doesn't. This might be a separate issue, so it can be considered for reference only.

      Now, getting back to the main issue, while analyzing the memory leak, I noticed that the setModel function in the "QQuickItemView" class was present in the call stack. Upon checking, I found that the disconnect and connect functions do not match as pairs.

      If we consider disconnect and Private::disconnect as disconnect, and connect and Private::connect as connect, the delegateChanged item only has connect but no disconnect.

      After fixing this issue and running the heaptrack test again, the graph in the "consumed page" now resembles a near-horizontal line, which seems to be the expected result.

       

       

      I would like to confirm whether this is the intended implementation or a bug.

      If it is the intended behavior, please share information on which part needs to be modified to fix the memory leak.

      • test code Qml file
        (png file is not attached, it could be anything in my opnion)
        import QtQuick
        Window {
            width: 640
            height: 480
            visible: true
            title: qsTr("Hello World")    Item {
              id: defaultLayers      property int indexValue : 0
              property int indexCount : 0      Item {
                  id: indicatorTest
                  x: 20
                  y: 20
                  width: 90
                  height: 244          Component {
                       id: indicatorComponent
                       Image {
                           id: componentImage
                           width: 12
                           height: 12
                           source: "file:/Users/jaejin/Downloads/penguin.png"
                       }
                  }          ListView {
                       id: indicatorListview
                       width: 12
                       height: (defaultLayers.indexValue * 12) + ((defaultLayers.indexValue - 1) * 6)
                       anchors.centerIn: parent
                       model: defaultLayers.indexValue
                       delegate: indicatorComponent
                       spacing: 6
                       focus: true
                  }          Timer {
                       id: testTimer
                       interval: 100
                       running: true
                       repeat: true
                       onTriggered: {
                           defaultLayers.indexValue = (defaultLayers.indexValue + 1) % 10
                           defaultLayers.indexCount = defaultLayers.indexCount + 1
                           if (defaultLayers.indexCount >= 20000) {
                                Qt.quit();
                           }
                       }
                  }
              }      Component.onCompleted: {
                  testTimer.start()
              }
            }}
         

        what I changed code

      in qtdeclarative repo,  src/quick/items/qquickitemview.cpp

      // code placeholder
      
      void QQuickItemView::setModel(const QVariant &m)
      {
          ....
          if (d->model) {
              disconnect(... modelUpdated ...);
              disconnect(... initItem ...);
              disconnect(... createdItem ...);
              disconnect(... destroyItem ...);
              if ( ... delegateModel = ... (d->model)) {
                  disconnect(delegateModel, ... itemPooled ...);
                  disconnect(delegateModel, ... itemReused ...);
                  // could not find delegateChanged disconnect 
                  // QObjectPrivate::disconnect(delegateModel, &QQmlDelegateModel::delegateChanged, d, &QQuickItemViewPrivate::applyDelegateChanged);
              }
          }
          ....
          ....
      
          if (d->model) {
              d->bufferMode ... 
              connect(d->model, ... createdItem ...);
              connect(d->model, ... initItem ...);
              connect(d->model, ... destroyingItem ...);
              if (... delegateModel = ... (d->model)) {
                  connect(delegateModel, ... itemPooled ...);
                  connect(delegateModel, ... itemReused ... );        
              }
              if (isComponentComplete()) {
                  ...
              }
              connect(... modelUpdated ... )
              if ( ... dataModel = ...(d->model))
                  QObjectPrivate::connect(dataModel, &QQmlDelegateModel::delegatedChanged, d, &QQuickItemViewPrivate::applyDelegateChange);
              emit ...
      
          }
          ...
      }

       

      • test with below command
        • QT_WAYLAND_DISABLE_WINDOWDECORATION=1 WAYLAND_DISPLAY=wayland-1 XDG_RUNTIME_DIR=/run/user/1000 QT_QPA_PLATFORM=wayland

      Attachments

        1. heaptrackv5518.zst
          4.41 MB
        2. heaptrackv622rev.zst
          4.03 MB
        3. heaptrackv682.zst
          3.64 MB
        4. image-2025-03-05-14-13-08-218.png
          image-2025-03-05-14-13-08-218.png
          40 kB
        5. image-2025-03-05-14-14-33-856.png
          image-2025-03-05-14-14-33-856.png
          48 kB
        For Gerrit Dashboard: QTBUG-134320
        # Subject Branch Project Status CR V

        Activity

          People

            srutledg Shawn Rutledge
            jae-jin Jae-jin Lee
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There is 1 open Gerrit change