Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QQmlEngine garbage collector
Forum Updated to NodeBB v4.3 + New Features

QQmlEngine garbage collector

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
15 Posts 2 Posters 2.7k 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.
  • KroMignonK KroMignon

    @Rugaru said in QQmlEngine garbage collector:

    So if I add message handling to the while loop QApplication::processEvents(); - can this solve the problem?

    For me, the real clean solution would be to use a timer, so you won't have any active wait.
    This will also reduce the CPU usage!

    auto tmr = new QTimer(this);
    
    connect(tmr, &QTimer::timeout, [this]() {
          MyCore.Debug("test");
          CreateSOA();
    });
    
    tmr->setInterval(1000);
    tmr->setSingleShort(false);
    tmr->start();
    
    R Offline
    R Offline
    Rugaru
    wrote on last edited by
    #5

    @KroMignon said in QQmlEngine garbage collector:

    @Rugaru said in QQmlEngine garbage collector:

    So if I add message handling to the while loop QApplication::processEvents(); - can this solve the problem?

    For me, the real clean solution would be to use a timer, so you won't have any active wait.
    This will also reduce the CPU usage!

    auto tmr = new QTimer(this);
    
    connect(tmr, &QTimer::timeout, [this]() {
          MyCore.Debug("test");
          CreateSOA();
    });
    
    tmr->setInterval(1000);
    tmr->setSingleShort(false);
    tmr->start();
    

    This is about C++ code.
    But my task is to make the garbage collector work correctly when using JavaScript.
    In a real project, API functions are implemented that the user can call from his own scripts on JavaScript.
    This test project and script shows the essence of the problem without unnecessary code sections.

    KroMignonK 1 Reply Last reply
    0
    • R Rugaru

      @KroMignon said in QQmlEngine garbage collector:

      @Rugaru said in QQmlEngine garbage collector:

      So if I add message handling to the while loop QApplication::processEvents(); - can this solve the problem?

      For me, the real clean solution would be to use a timer, so you won't have any active wait.
      This will also reduce the CPU usage!

      auto tmr = new QTimer(this);
      
      connect(tmr, &QTimer::timeout, [this]() {
            MyCore.Debug("test");
            CreateSOA();
      });
      
      tmr->setInterval(1000);
      tmr->setSingleShort(false);
      tmr->start();
      

      This is about C++ code.
      But my task is to make the garbage collector work correctly when using JavaScript.
      In a real project, API functions are implemented that the user can call from his own scripts on JavaScript.
      This test project and script shows the essence of the problem without unnecessary code sections.

      KroMignonK Offline
      KroMignonK Offline
      KroMignon
      wrote on last edited by
      #6

      @Rugaru said in QQmlEngine garbage collector:

      This is about C++ code.
      But my task is to make the garbage collector work correctly when using JavaScript.
      In a real project, API functions are implemented that the user can call from his own scripts on JavaScript.
      This test project and script shows the essence of the problem without unnecessary code sections.

      Sorry, had misunderstood the code.

      So same with JavaScript could be (not tested sorry):

      var myVar = setInterval(myTimer, 1000);
      
      function myTimer() {
            MyCore.Debug("test");
            CreateSOA();
      }
      

      But always remember, if you want to use Qt, you have to ensure you are not breaking event loop. And QML is running in main thread. So a forever loop is not possible in combination with Qt/QML.

      It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

      R 2 Replies Last reply
      1
      • KroMignonK KroMignon

        @Rugaru said in QQmlEngine garbage collector:

        This is about C++ code.
        But my task is to make the garbage collector work correctly when using JavaScript.
        In a real project, API functions are implemented that the user can call from his own scripts on JavaScript.
        This test project and script shows the essence of the problem without unnecessary code sections.

        Sorry, had misunderstood the code.

        So same with JavaScript could be (not tested sorry):

        var myVar = setInterval(myTimer, 1000);
        
        function myTimer() {
              MyCore.Debug("test");
              CreateSOA();
        }
        

        But always remember, if you want to use Qt, you have to ensure you are not breaking event loop. And QML is running in main thread. So a forever loop is not possible in combination with Qt/QML.

        R Offline
        R Offline
        Rugaru
        wrote on last edited by
        #7

        @KroMignon Understood, thanks!
        I will try this option after work.

        1 Reply Last reply
        0
        • KroMignonK KroMignon

          @Rugaru said in QQmlEngine garbage collector:

          This is about C++ code.
          But my task is to make the garbage collector work correctly when using JavaScript.
          In a real project, API functions are implemented that the user can call from his own scripts on JavaScript.
          This test project and script shows the essence of the problem without unnecessary code sections.

          Sorry, had misunderstood the code.

          So same with JavaScript could be (not tested sorry):

          var myVar = setInterval(myTimer, 1000);
          
          function myTimer() {
                MyCore.Debug("test");
                CreateSOA();
          }
          

          But always remember, if you want to use Qt, you have to ensure you are not breaking event loop. And QML is running in main thread. So a forever loop is not possible in combination with Qt/QML.

          R Offline
          R Offline
          Rugaru
          wrote on last edited by
          #8

          @KroMignon said in QQmlEngine garbage collector:

          @Rugaru said in QQmlEngine garbage collector:

          This is about C++ code.
          But my task is to make the garbage collector work correctly when using JavaScript.
          In a real project, API functions are implemented that the user can call from his own scripts on JavaScript.
          This test project and script shows the essence of the problem without unnecessary code sections.

          Sorry, had misunderstood the code.

          So same with JavaScript could be (not tested sorry):

          var myVar = setInterval(myTimer, 1000);
          
          function myTimer() {
                MyCore.Debug("test");
                CreateSOA();
          }
          

          But always remember, if you want to use Qt, you have to ensure you are not breaking event loop. And QML is running in main thread. So a forever loop is not possible in combination with Qt/QML.

          The timer option did not work, because I do not use QML, but only its JavaScript interpreter, as soon as I run the main function and start the timer in it, the script ends its work.
          I corrected the code a bit in the first post, added the latest changes to it.
          For the test, I tried to transfer execution to the main thread, before and after SleepMs - call the processEvents, set the garbage collector flags for QQmlEngine, but this did not fix the situation.
          In my application, these scripts are executed exclusively in a parallel thread, nothing from QML (except the JS interpreter) is used.
          For each script, a separate thread is launched, the specified function is executed, and after execution the thread ends.
          Are there any other options to make the garbage collector work without changing the JS code?

          function main()
          {
             while (true)
             {
                MyCore.Debug("test");
                CreateSOA();
                MyCore.SleepMs(1000);
             }
          }
          
          function CreateSOA()
          {
             for (var i = 0; i < 10000; i++)
             {
                var obj = MyCore.GenerateObjectWithArray();
             }
             // all obj must be deleted here, but it doesn't happen
          }
          
          KroMignonK 1 Reply Last reply
          0
          • R Rugaru

            @KroMignon said in QQmlEngine garbage collector:

            @Rugaru said in QQmlEngine garbage collector:

            This is about C++ code.
            But my task is to make the garbage collector work correctly when using JavaScript.
            In a real project, API functions are implemented that the user can call from his own scripts on JavaScript.
            This test project and script shows the essence of the problem without unnecessary code sections.

            Sorry, had misunderstood the code.

            So same with JavaScript could be (not tested sorry):

            var myVar = setInterval(myTimer, 1000);
            
            function myTimer() {
                  MyCore.Debug("test");
                  CreateSOA();
            }
            

            But always remember, if you want to use Qt, you have to ensure you are not breaking event loop. And QML is running in main thread. So a forever loop is not possible in combination with Qt/QML.

            The timer option did not work, because I do not use QML, but only its JavaScript interpreter, as soon as I run the main function and start the timer in it, the script ends its work.
            I corrected the code a bit in the first post, added the latest changes to it.
            For the test, I tried to transfer execution to the main thread, before and after SleepMs - call the processEvents, set the garbage collector flags for QQmlEngine, but this did not fix the situation.
            In my application, these scripts are executed exclusively in a parallel thread, nothing from QML (except the JS interpreter) is used.
            For each script, a separate thread is launched, the specified function is executed, and after execution the thread ends.
            Are there any other options to make the garbage collector work without changing the JS code?

            function main()
            {
               while (true)
               {
                  MyCore.Debug("test");
                  CreateSOA();
                  MyCore.SleepMs(1000);
               }
            }
            
            function CreateSOA()
            {
               for (var i = 0; i < 10000; i++)
               {
                  var obj = MyCore.GenerateObjectWithArray();
               }
               // all obj must be deleted here, but it doesn't happen
            }
            
            KroMignonK Offline
            KroMignonK Offline
            KroMignon
            wrote on last edited by
            #9

            @Rugaru said in QQmlEngine garbage collector:

            // all obj must be deleted here, but it doesn't happen

            This will never happen!
            Garbarge Collector is called asynchronously, when JavaScript Engine have time for it.

            You can call it directly if you want with gc()

            See https://doc.qt.io/qt-5/qtquick-performance.html for mode details.

            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

            1 Reply Last reply
            1
            • R Offline
              R Offline
              Rugaru
              wrote on last edited by
              #10

              @KroMignon said in QQmlEngine garbage collector:

              You can call it directly if you want with gc()

              I tried adding this to the code, but the garbage collector still wouldn't start

              function CreateSOA()
              {
                 for (var i = 0; i < 10000; i++)
                 {
                    var obj = MyCore.GenerateObjectWithArray();
                 }
                 gc();
                 // all obj must be deleted here, but it doesn't happen
              }
              

              In addition, I added to the SleepMs function forcing a call to the garbage collector from C++ code with processing the event queue, but that also gave nothing

              void CScriptEngine::SleepMs(int delay)
              {
              	QApplication::processEvents();
              	thread()->msleep(delay);
              	QApplication::processEvents();
              	m_scriptHandle->m_jsEngine->collectGarbage();
              	QApplication::processEvents();
              }
              

              In the documentation:

              While garbage collection will be automatically triggered by the JavaScript engine when the amount of available free memory is low

              But this does not happen either, when the memory is full, a crash occurs

              KroMignonK 1 Reply Last reply
              0
              • R Rugaru

                @KroMignon said in QQmlEngine garbage collector:

                You can call it directly if you want with gc()

                I tried adding this to the code, but the garbage collector still wouldn't start

                function CreateSOA()
                {
                   for (var i = 0; i < 10000; i++)
                   {
                      var obj = MyCore.GenerateObjectWithArray();
                   }
                   gc();
                   // all obj must be deleted here, but it doesn't happen
                }
                

                In addition, I added to the SleepMs function forcing a call to the garbage collector from C++ code with processing the event queue, but that also gave nothing

                void CScriptEngine::SleepMs(int delay)
                {
                	QApplication::processEvents();
                	thread()->msleep(delay);
                	QApplication::processEvents();
                	m_scriptHandle->m_jsEngine->collectGarbage();
                	QApplication::processEvents();
                }
                

                In the documentation:

                While garbage collection will be automatically triggered by the JavaScript engine when the amount of available free memory is low

                But this does not happen either, when the memory is full, a crash occurs

                KroMignonK Offline
                KroMignonK Offline
                KroMignon
                wrote on last edited by
                #11

                @Rugaru said in QQmlEngine garbage collector:

                But this does not happen either, when the memory is full, a crash occurs

                By the way, I don't really understand why you are using QQmlEngine for this and no QtScriptEngine?
                If I understanding what you want to do, you are not using any QML feature and don't want to do it.

                I guess QtScriptEngine better fits you needs (cf. https://doc.qt.io/qt-5/qtscript-index.html)

                It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                R 1 Reply Last reply
                0
                • KroMignonK KroMignon

                  @Rugaru said in QQmlEngine garbage collector:

                  But this does not happen either, when the memory is full, a crash occurs

                  By the way, I don't really understand why you are using QQmlEngine for this and no QtScriptEngine?
                  If I understanding what you want to do, you are not using any QML feature and don't want to do it.

                  I guess QtScriptEngine better fits you needs (cf. https://doc.qt.io/qt-5/qtscript-index.html)

                  R Offline
                  R Offline
                  Rugaru
                  wrote on last edited by
                  #12

                  @KroMignon said in QQmlEngine garbage collector:

                  I guess QtScriptEngine better fits you needs (cf. https://doc.qt.io/qt-5/qtscript-index.html)

                  Right now I'm using QtScriptEngine, the garbage collector works perfectly in it, but it implements support for ECMA-262 (2011, if I'm not mistaken) and lacks most of the convenient new features of the language
                  I want to switch to the QML engine (because QtScriptEngine is not supported for a long time, and in Qt6 it is not at all) just for this, but it has problems with the garbage collector, which I still can't solve normally.

                  KroMignonK 1 Reply Last reply
                  0
                  • R Rugaru

                    @KroMignon said in QQmlEngine garbage collector:

                    I guess QtScriptEngine better fits you needs (cf. https://doc.qt.io/qt-5/qtscript-index.html)

                    Right now I'm using QtScriptEngine, the garbage collector works perfectly in it, but it implements support for ECMA-262 (2011, if I'm not mistaken) and lacks most of the convenient new features of the language
                    I want to switch to the QML engine (because QtScriptEngine is not supported for a long time, and in Qt6 it is not at all) just for this, but it has problems with the garbage collector, which I still can't solve normally.

                    KroMignonK Offline
                    KroMignonK Offline
                    KroMignon
                    wrote on last edited by
                    #13

                    @Rugaru said in QQmlEngine garbage collector:

                    I want to switch to the QML engine (because QtScriptEngine is not supported for a long time, and in Qt6 it is not at all) just for this, but it has problems with the garbage collector, which I still can't solve normally.

                    Sorry, I can't help you more on this issue.
                    Perhaps you should submit a ticket at QT BugReport ==> https://bugreports.qt.io

                    It maybe possible that, with Qt6 there have been optimizations done on QQmlEngine for better scripting support.
                    I am waitting for Qt 6.2 before starting to work with Qt6, so I can not give you more information.

                    It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                    1 Reply Last reply
                    0
                    • R Offline
                      R Offline
                      Rugaru
                      wrote on last edited by
                      #14

                      Thank you for your help!
                      Yes, I will write a bug report and keep looking for options.

                      1 Reply Last reply
                      0
                      • R Offline
                        R Offline
                        Rugaru
                        wrote on last edited by
                        #15

                        Possible solution to the problem: https://bugreports.qt.io/browse/QTBUG-94566
                        Worked for me, but it's a workaround

                        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