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

QML loader is leaking memory on each new loaded type

    XMLWordPrintable

Details

    Description

      When a QML type is loaded for the first time using Loader, QML engine allocates some kind of meta-data that is reused on subsequent loads of the same type. Unfortunately, this meta-data seems to be never released again, even if all instances of the loaded type were unloaded and trimComponentCache() and even clearComponentCache() were called.

      A "new QML type" seems to be created whenever a component is described in a new file or when a custom property is declared inside an inline component declaration.

      I have created a test project that generates many copies of the same, quite simple component and loads them one by one using the same loader. The loaded component consists of about 11 rectangles, 9 texts, one image, one linear gradient and one fast blur on top of all of them. The test project uses TC Malloc in order to show how much memory is actually used and how much overhead there is.

      Steps to use the test project (only tested on linux):

      • install tcmalloc
      • ./generate 20000
      • qmake .
      • make
      • QV4_MM_STATS=1 ./run
      • click on small green rectangle to print memory stats and watch memory grow
      • click on white background to start loading
      • wait until all 20000 components were loaded, then click on white background to stop loading
      • click on small green rectangle to print memory stats
      • you can click yellow and red rectangle to trim/clear component cache as well

      You can start ./mem.sh to monitor memory on another terminal.

      I have also tried to load one rectangle with one text 100000 times with similar results.

      On my machine, I see memory consumption grow by about 2.4 KB per load on average for 20000 components. Note that at any time, no more than 25 QML components are actually loaded and shown (one instance of the test component).

      The memory does not grow any more when the same type is loaded again. However, this issue basically makes it impossible to create large long-running QML applications with many custom types, since the memory consumption will inevitably grow when more and more features of the application are used, even though we unload no longer used screens.

      The issue happens both when QML files are loaded from disk and when they are compiled with commercial qt quick compiler.

      See also logs and statistics I collected on my machine in doc/ directory.

      Attachments

        1. 0001-Automate-measurements-and-added-valgrind-support-use.patch
          4 kB
          Simon Hausmann
        2. 0001-Fix-memory-of-QML-type-registry-not-freed-when-clear.patch
          237 kB
          Simon Hausmann
        3. 0001-Loader-in-Bla.qml.patch
          2 kB
          Alex Busenius
        4. 0001-WIP-Squeeze-various-vectors-when-trimming-caches.patch
          4 kB
          Simon Hausmann
        5. 100000-comp-same-synchronous.log.gz
          2 kB
          Alex Busenius
        6. 20k-patched-2-mmstats.log.gz
          12 kB
          Alex Busenius
        7. 20k-patched-3.log.gz
          18 kB
          Alex Busenius
        8. 6000-comp-different-synchronous.log.gz
          3 kB
          Alex Busenius
        9. Comp.qml
          3 kB
          Alex Busenius
        10. qmlloaderexample.tar.gz
          21 kB
          Alex Busenius
        11. test-valgrind.log.gz
          1012 kB
          Alex Busenius

        Issue Links

          Activity

            People

              shausman Simon Hausmann
              alexbusenius Alex Busenius
              Votes:
              3 Vote for this issue
              Watchers:
              14 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: