About StackView memory consumption
-
Hi all,
I met a problem about the StackView, could someone help?
I pushed a lot of items into the StackView and then popped them up.
But I found that the memory consumption kept the same as the status before I popped them up.
E.G.:I pushed 100 items into StackView, the memory consumption is 150m, after I popped all them up, the memory consumption is still 150m.I debugged the source code and found the items inside StackView already called destroy(), but why the memory are not released, could some one help?
-
Thank you for your attention!
singletonexporttoqml.h
@
#ifndef SINGLETONEXPORTTOQML
#define SINGLETONEXPORTTOQML#include <QQmlEngine>
#include <QtQml>
// First, define your QObject which provides the functionality.
class SingletonTypeExample : public QObject
{
Q_OBJECT
Q_PROPERTY (int someProperty READ someProperty WRITE setSomeProperty NOTIFY somePropertyChanged)public:
SingletonTypeExample(QObject* parent = 0)
: QObject(parent),
m_someProperty(0)
{
}~SingletonTypeExample() {} Q_INVOKABLE int doSomething() { setSomeProperty(5); return m_someProperty; } int someProperty() const { return m_someProperty; } void setSomeProperty(int val) { m_someProperty = val; emit somePropertyChanged(val); }
signals:
void somePropertyChanged(int newValue);private:
int m_someProperty;
};class ComponentCacheManager : public QObject {
Q_OBJECT
public:
ComponentCacheManager(QQmlEngine *engine) : engine(engine) { }Q_INVOKABLE void trim() { engine->trimComponentCache(); } Q_INVOKABLE void clear() { engine->clearComponentCache(); }
private:
QQmlEngine *engine;
};// Second, define the singleton type provider function (callback).
static QObject *example_qobject_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(engine)
Q_UNUSED(scriptEngine)SingletonTypeExample *example = new SingletonTypeExample(); return example;
}
// Second, define the singleton type provider function (callback).
static QObject *example_ComponentCacheManager_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
Q_UNUSED(scriptEngine)ComponentCacheManager *example = new ComponentCacheManager(engine); return example;
}
#endif // SINGLETONEXPORTTOQML
@
main.cpp
@
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlEngine>
#include <QtQml>
#include "singletonexporttoqml.h"int main(int argc, char *argv[])
{
QApplication app(argc, argv);QQmlApplicationEngine engine; qmlRegisterSingletonType<SingletonTypeExample>("Qt.example.qobjectSingleton", 1, 0, "MyApi", example_qobject_singletontype_provider); qmlRegisterSingletonType<ComponentCacheManager>("Qt.example.ComponentCacheManager", 1, 0, "ComponentCacheManager", example_ComponentCacheManager_provider); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); return app.exec();
}
@main.qml
@
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import Qt.example.qobjectSingleton 1.0
import Qt.example.ComponentCacheManager 1.0ApplicationWindow
{
width: 800
height: 480
visible: trueColumn { id: col Button{ text: "pop" onClicked: { if(stack.depth == 1) { stack.clear() } else { stack.pop() } ComponentCacheManager.trim() ComponentCacheManager.clear() gc() } } Button{ text: "push: " + stack.depth onClicked: { stack.push(Qt.resolvedUrl("qrc:/HMIView.qml")) } } } StackView { y: 100 id: stack }
}
@
-
HMIView.qml
@
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import Qt.example.ComponentCacheManager 1.0
Rectangle {
id: hmiView
color: 'lightgreen'
property alias stack: pageStack
property string name: name
ListModel {
id: pageListModelListElement { name: "Navi" path: "qrc:/NaviView.qml" } ListElement { name: "Media" path: "qrc:/MediaView.qml" } ListElement { name: "Phone" path: "qrc:/PhoneView.qml" } } Column { spacing: 0 Label { height: 60 width: 800 id: currentPressed text:" current page stack depth is: " + stack.depth //anchors.left : appList.right } Row { Button { width: 50 height: 60 text: "Back" onClicked: { if(pageStack.depth == 1) { pageStack.clear() } else { pageStack.pop() } ComponentCacheManager.trim() ComponentCacheManager.clear() gc() } } Column { Label { height: 30 text: "push" } Label { height: 30 text: "replace" } } ListView { id: pageList width: 750 height: 30 orientation: ListView.Horizontal model: pageListModel delegate: Column{ Button { width: 100 height: 30 text: name onClicked: { onClicked: pageStack.push({item:Qt.resolvedUrl(path), properties: {name: text}}) } } Button { width: 100 height: 30 text: name onClicked: { onClicked: { if(pageStack.find(function(item){return item.name === name})) { pageStack.pop(stack.find(function(item){return item.name === name})) } else { pageStack.push({item:Qt.resolvedUrl(path), properties: {name: text}}) } } } } } //focus: true } } StackView { height: 200 width:800 id: pageStack } }
}
@
MediaView.qml
@
import QtQuick 2.4
import QtQuick.Controls 1.3HMIView
{
color: 'lightgreen'
}
@NaviView.qml
@
import QtQuick 2.4
import QtQuick.Controls 1.3HMIView
{
color: 'lightblue'
}
@PhoneView.qml
@
import QtQuick 2.4
import QtQuick.Controls 1.3HMIView
{
color: 'orange'
}
@ -
This isn't really what I was after. For future reference, see http://sscce.org/ -- when trying to ask someone for help, posting the smallest possible (ideally self-contained) example should be what you aim for. The easier you make it for someone else to try reproduce your problem, the easier you make it for them to help you.
That aside, from using a heap profiler, and pressing the top push buttom 40 times (and then popping it all) and measuring the allocations that persisted from the start of measuring until the button was popped back to a 0 count:
- You have 8.19mb tied up in WTF::OsAllocator::reserveAndCommit. This is either JIT generated code or the JS heap. I'm not sure which without further digging.
- You have 1.66mb tied up in 30 x 56kb allocations (QQmlJavaScriptExpression)
Everything else pales into insignificance apart from those (the next biggest stack growth is from some 2 KB-sized allocations from various sources, most of which come from inside the OS X libraries -- so either just a general "fact of life" from caches being filled, or something specific to OS X)
My conclusion is likely similar to my looking at TableView recently: the use of JavaScript for what should be quite simple logic is imposing unnecessary overhead in StackView. Whether or not that could be improved on, I don't know without digging quite a bit further.