Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Japanese
  4. QMLを解放する方法
Forum Updated to NodeBB v4.3 + New Features

QMLを解放する方法

Scheduled Pinned Locked Moved Japanese
7 Posts 2 Posters 8.2k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    SAHI
    wrote on last edited by
    #1

    CPUのメモリが256MBしかないため、表示していないQMLは解放して、メモリの使用量を削減したいと思っています。
    以下のように実装していますが、この方法では表示前と解放後のメモリの使用量が一致しません。

    Item {
    id:container
    property var objTmp
    function open(){
    if(objTmp === undefined || objTmp === null){
    var component = Qt.createComponent("***.qml")
    if(component.status == Component.Ready){
    objTmp = component.createObject(container)
    }
    }
    }
    }
    function close(){
    if(objTmp !== undefined && objTmp !== null){
    objTmp.destroy()
    }
    }
    }

    Loaderに動的ロード(使用時はsourceにQMLをセットし、未使用時は””をセット)したときも同様に一致しません。

    QMLを完全に解放する方法は無いのでしょうか?
    ご教授願います。

    1 Reply Last reply
    0
    • T Offline
      T Offline
      Tasuku Suzuki
      wrote on last edited by
      #2

      QML ではメモリの解放はガベージコレクションによって行われるため destroy() を実行した時点では解放されません。

      手動で解放するには以下のメソッドを(C++ から)実行する必要があります。
      http://doc.qt.io/qt-5/qjsengine.html#collectGarbage

      ドキュメントには書いていない(現時点では非公式な?方法)ですが、ガベージコレクタのソースコードを読むといくつかの環境変数を設定することで使用するメモリの量や GC の戦略の変更が可能のようですので、そちらも試してみてはいかがでしょうか。
      http://git.qt-users.jp/git/?p=mirror/qt/qtdeclarative.git;a=blob;f=src/qml/jsruntime/qv4mm.cpp;h=d5576b400a4af76a861de9abdf2e829f198a6bc6;hb=HEAD#l222

      1 Reply Last reply
      0
      • S Offline
        S Offline
        SAHI
        wrote on last edited by
        #3

        ご回答ありがとうございます。

        QJSEngine::collectGarbageはどのように使用すればよいのでしょうか?
        以前trimComponentCache()を使ったときは効果がなかったのですが、
        これとは異なるものでしょうか?

        素人質問で申し訳ありませんが、ご教授願います。

        1 Reply Last reply
        0
        • T Offline
          T Offline
          Tasuku Suzuki
          wrote on last edited by
          #4

          QJSEngine は QQmlEngine の基底クラスなので以前に timComponentCache() を使ったことがあるのでしたら同じように collectGarbage() も使えるはずです。

          collectGarbage() はメモリの解放処理で、trimComponentCache() はキャッシュの解放処理なので別々の処理になります。詳細はドキュメントや実際の実装を参照してください。

          1 Reply Last reply
          0
          • S Offline
            S Offline
            SAHI
            wrote on last edited by
            #5

            collectGarbage()を実行してみましたがSegmentation faultが発生してしまいました。
            trimComponentCache()は正しく動作します。
            どういった原因が考えられますか?

            度々すみませんが、よろしくお願いします。

            1 Reply Last reply
            0
            • T Offline
              T Offline
              Tasuku Suzuki
              wrote on last edited by
              #6

              実際のコードがないので詳細はわかりませんが、原因は Qt の collectGarbage() にバグがあるか、SAHI さんのコードにバグがあるかでしょう。

              もし Qt 側のバグであれば、バグレポを書いていただけると助かります。

              1 Reply Last reply
              0
              • S Offline
                S Offline
                SAHI
                wrote on last edited by
                #7

                かなり時間が経過してしまいました。
                Qt側にバグがあると言えるようなスキルは無いので、自分なりに色々と試してみましたが改善しませんでした。
                ちょっと長いですが、コードを添付しますので、ご助言をお願いします。

                (main.cpp)
                QtQuick2ApplicationViewer viewer;
                QQmlEngine* qengine = viewer.engine();
                waitthread waitproc;
                waitproc.setqengine(qengine);
                waitproc.start();

                (waitthread.h)
                #ifndef WAITTHREAD_H
                #define WAITTHREAD_H

                #include <QThread>
                #include <QMutex>
                #include <QQmlEngine>

                class waitthread : public QThread
                {
                Q_OBJECT
                public:
                explicit waitthread(QObject *parent = 0);
                ~waitthread();
                void stop();
                void setqengine(QQmlEngine *qmlenginepointer);

                public slots:

                protected:
                void run();

                private:
                QString state;
                volatile int running;
                QQmlEngine *qmlenginep;
                };

                #endif // WAITTHREAD_H

                (waitthread.cpp)
                #include <QApplication>
                #include <QDebug>
                #include "waitthread.h"

                waitthread::waitthread(QObject *parent) : QThread(parent)
                {
                state = "Thread Stop";
                running = 0;
                qmlenginep = NULL;
                }

                waitthread::~waitthread()
                {
                }

                void waitthread::run()
                {
                running = 1;
                bool onoff = false;
                while(running == 1){
                state = "Thread Running";

                    msleep(10000);
                

                // qmlenginep->trimComponentCache();
                // qmlenginep->collectGarbage();
                // QApplication::processEvents(QEventLoop::AllEvents);

                // qDebug() << "Trim Component Cache !!";

                    if(onoff){
                        qmlenginep->trimComponentCache();
                        qDebug() << "Trim Component Cache !!";
                    }
                    else{
                        qmlenginep->collectGarbage();
                        qDebug() << "collectGarbage !!";
                    }
                    QApplication::processEvents(QEventLoop::AllEvents);
                    onoff = !onoff;
                
                }
                state = "Thread Stop";
                

                }

                void waitthread::setqengine(QQmlEngine *qmlenginepointer)
                {
                qmlenginep = qmlenginepointer;
                }

                以上のコードで10秒置きにcollectGarbageとtrimComponentCacheを実行していますが、最初のcollectGarbageでSegmentation faultが発生してプログラムが突然終了します。

                よろしくお願いします。

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved