这是第一篇,资料原文在这里
-
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)!
- Static:
-
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
- Yes, if an object has
-
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
- JavaScript in QML can be used in
-
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
- Triggered eigher through
-
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
- are allocated from a separate Javascript heap
-
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
- Use an up to date version of Qt
- For memory constrained environments
- Less is more (especially for delegates)
- Plan for dynamic object loading/unloading
- Limit the ammount of Javascript
- A conceptual understanding how QML memory management works
这是第二篇,资料原文在这里
注意该整理文第一句与上面的内容可能存在一定矛盾,也有可能是因为理解不到位而感觉有矛盾,为避免内容遗漏,依然在这里保留
- 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())