Skip to content

Latest commit

 

History

History
133 lines (107 loc) · 5.68 KB

生命周期与垃圾回收的参考信息.md

File metadata and controls

133 lines (107 loc) · 5.68 KB

该文档是对两篇关于“QML里的生命周期与垃圾回收”的非官方资料进行搜集与整理的结果,由于原文关于这方面内容比较散乱,整理之后方便阅读

这是第一篇,资料原文在这里

A deep dive into QML memory management internals

  • QML is a declarative language used to describe user interfaces

    • hierarchy and relationship of UI elements/objects
  • Javascript can be embedded to implement UI logic

  • QML object types are implemented in C++

    • Non-visual QML elements derive directly from QObject
    • Visual QML elements derive from QQuickItem(which is derived from QObject)
    • E.g. a "Rectangle{}" is implemented by C++ class QQuickRectangle
  • The QML source describes how to assemble a tree of QObjects

  • Methods to create QML objects

    • Static:
      • QQuickView::setSource(QUrl("..."))
      • QQmlApplicationEngine::load(QUrl("..."))
    • Dynamic:
      • Loader
      • Qt.createComponent()/component.createObject(parent)
    • All these methods create a tree of QML objects
    • An object that gets destroyed will also (recursively) destroy its children
      • The same mechanism as in Qt
    • No garbage collection involved (for the QML objects itself)!
  • QML properties

    • Rectangle { property int foo; property var bar }
    • Properties defined in QML source need to
      • be stored somewhere
      • integrate with the rest of the metaobject system
    • QQmlVMEMetaObject takes care of that
    • typed properties (non-var) are stored on the process heap (QQmlVMEVariant objects)
    • var properties are stored as QV4::Values in an QV4::Array which resides on the JS heap
    • This will change with Qt5.6
      • QQmlVMEVariant weighs in at 8sizeof(void) + sizeof(int) => 36/72 bytes
      • Everything will be stored in a QV4::Value (8 bytes)
    • What happens to a property when its object is deleted?
      • The parts allocated on the process heap are directly deleted with the object
      • The parts stored on the JS-side are orphaned and left for garbage collection
    • What happens to a QML object stored in a var property?
      • Still cleaned up via the QObject hierarchy, no GC
  • Is the GC ever collecting QObjects?

    • Yes, if an object has
      • QQmlEngine::JavaScriptOwnership
      • no parent
      • no remaining JavaScript references
  • Will the GC ever collect a visible QObject?

    • No, the visual parent will keep its visual children alive
  • QML objects

    • are allocated from the process heap
    • deallocated via delete/deleteLater
  • Children are cleaned up via the Qt object hierarchy

  • QML allows you to control the life-time of objects

    • (typically) no garbage collection involved
  • Make use of it!

    • Loader/dynamic object creation
    • Unload elements no longer needed
    • Make sure to call .destroy() on dynamically created components
  • Javascript

    • JavaScript in QML can be used in
      • property bindings
      • signal handlers
      • custom methods
      • standalone
    • The code for the various JavaScript types is written in C++
    • Instances are allocated from a separate garbage collected JS heap
  • The only way to deallocate JS objects is to run the GC

  • How dose the GC work?

    • Triggered eigher through
      • an allocation (depending on usage metrics)
      • manually (JS/C++)
    • Runs in the main thread, blocks the application
    • The implementation can be found in QV4::MemoryManager
  • Objectives of the GC

    • The GC is freeing unused objects from the JS heap
  • Should I manually trigger the GC?

    • In general: no
    • Exceptions to the rule:
      • the application is idle (and no one is looking)
    • after unloading a large QML component
      • Ensure to pass through the eventloop once, before calling gc()
      • Try to run malloc_trim(0) to encourage malloc to give memory back to the OS
  • Javascript objects

    • are allocated from a separate Javascript heap
      • with the exception of large items
    • deallocated only via the GC
      • also large items are gc'd
  • The GC is triggered either

    • through utilisation metrics
    • manually
  • Conclusion

    • A conceptual understanding how QML memory management works
      • QML: allows you to control the life-time of objects
      • Javascript: No direct control over object life-time
    • Memory management has improved throughout Qt5
      • Use an up to date version of Qt
        • if you can't, be aware of version specific behaviour
        • E.g. avoid memory peaks with a Qt < 5.5
    • For memory constrained environments
      • Less is more (especially for delegates)
      • Plan for dynamic object loading/unloading
      • Limit the ammount of Javascript

这是第二篇,资料原文在这里

注意该整理文第一句与上面的内容可能存在一定矛盾,也有可能是因为理解不到位而感觉有矛盾,为避免内容遗漏,依然在这里保留

QML tricks and treats

  • the various object-like entities' runtime ownership -- there are:
    • QML side objects (QtObject and Item instances), garbage collected by the QML engine
    • JS objects managed by the JS runtime
    • (the strangest thing) "var" properties which are "not QML objects (and certainly not Javascript object eigher)", quoting the docs
      • note: whether a QObject's lifetime is managed by the QML engine, can also be set on a per-object basis manually (see docs on QqmlEngine::ObjectOwenership())