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?



  • Can you create an example that can be run using qmlscene?



  • 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.0

    ApplicationWindow
    {
    width: 800
    height: 480
    visible: true

    Column
    {
        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: pageListModel

        ListElement {
            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.3

    HMIView
    {
    color: 'lightgreen'
    }
    @

    NaviView.qml
    @
    import QtQuick 2.4
    import QtQuick.Controls 1.3

    HMIView
    {
    color: 'lightblue'
    }
    @

    PhoneView.qml
    @
    import QtQuick 2.4
    import QtQuick.Controls 1.3

    HMIView
    {
    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.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.