Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Memory leak using QThread issue
Forum Updated to NodeBB v4.3 + New Features

Memory leak using QThread issue

Scheduled Pinned Locked Moved Solved General and Desktop
35 Posts 5 Posters 13.7k Views 2 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.
  • Cobra91151C Offline
    Cobra91151C Offline
    Cobra91151
    wrote on last edited by Cobra91151
    #1

    Hi! I have made a changelog feature to my application. I have created worker class and connect all signals and slots with QThread. The problem is when I start a thread to update data more then one time it begin to leak RAM memory.

    Code:

     appCheckUpdate = new CheckUpdates();
     appCheckUpdatesThread = new QThread();
     appCheckUpdate->moveToThread(appCheckUpdatesThread);
     connect(appCheckUpdatesThread, &QThread::started, appCheckUpdate, &CheckUpdates::checkUpdate);
     connect(appCheckUpdate, &CheckUpdates::updateData, this, &Changelog::getUpdateData);
     connect(appCheckUpdate, &CheckUpdates::networkError, this, &Changelog::changeLogUpdateError);
     connect(appCheckUpdate, &CheckUpdates::localeError, this, &Changelog::updateLocaleError);
     connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit, Qt::DirectConnection);
     appCheckUpdatesThread->start();
    

    When I create this on the stack:

      appCheckUpdate.moveToThread(&appCheckUpdatesThread);
      connect(&appCheckUpdatesThread, &QThread::started, &appCheckUpdate, &CheckUpdates::checkUpdate);
      connect(&appCheckUpdate, &CheckUpdates::updateData, this, &Changelog::getUpdateData);
      connect(&appCheckUpdate, &CheckUpdates::networkError, this, &Changelog::changeLogUpdateError);
      connect(&appCheckUpdate, &CheckUpdates::localeError, this, &Changelog::updateLocaleError);
      connect(&appCheckUpdate, &CheckUpdates::finished, &appCheckUpdatesThread, &QThread::quit, Qt::DirectConnection);
      appCheckUpdatesThread.start();
    

    It duplicates data and also leak is still present. How to fix this issue? Thanks in advance.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      In the first case, you don't seem to delete appCheckUpdate nor appCheckUpdateThread.

      As for the leak, how do you know you are leaking something ?

      Are you properly handling all resource in your custom classes ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      Cobra91151C 1 Reply Last reply
      0
      • SGaistS SGaist

        Hi,

        In the first case, you don't seem to delete appCheckUpdate nor appCheckUpdateThread.

        As for the leak, how do you know you are leaking something ?

        Are you properly handling all resource in your custom classes ?

        Cobra91151C Offline
        Cobra91151C Offline
        Cobra91151
        wrote on last edited by
        #3

        @SGaist

        I have checked the memory leak by Task Manager.

        I have some questions:

        1. Qt does not delete objects when use connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit, Qt::DirectConnection);?

        I thought when thread has been deleted than the object appCheckUpdate should be also deleted or not?

        1. So where do I have to delete those objects (in destructor)?

        Thanks in advance for your help.

        J.HilkJ 1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          A thread calling finished doesn't delete itself like that, it's your job to know when it should be deleted. If it's when CheckUpdates::finished then connect the deleteLater function to it.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          3
          • Cobra91151C Cobra91151

            @SGaist

            I have checked the memory leak by Task Manager.

            I have some questions:

            1. Qt does not delete objects when use connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit, Qt::DirectConnection);?

            I thought when thread has been deleted than the object appCheckUpdate should be also deleted or not?

            1. So where do I have to delete those objects (in destructor)?

            Thanks in advance for your help.

            J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #5

            @Cobra91151 as an additional note,

            Using Qt::DirectConnection instead of Qt::QueuedConnection is asking for trouble!
            Signal/Slot Connections are threadsave because they are automatically queued, accpet if you give it Qt::DirectConnection as a 5th parameter.


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            Cobra91151C 1 Reply Last reply
            1
            • J.HilkJ J.Hilk

              @Cobra91151 as an additional note,

              Using Qt::DirectConnection instead of Qt::QueuedConnection is asking for trouble!
              Signal/Slot Connections are threadsave because they are automatically queued, accpet if you give it Qt::DirectConnection as a 5th parameter.

              Cobra91151C Offline
              Cobra91151C Offline
              Cobra91151
              wrote on last edited by
              #6

              @SGaist
              @J.Hilk

              I will try it. Thanks for the suggestions.

              1 Reply Last reply
              0
              • Cobra91151C Offline
                Cobra91151C Offline
                Cobra91151
                wrote on last edited by
                #7

                I use connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::deleteLater); but then I get warning: QThread: Destroyed while thread is still running.

                So should I connection like this:

                connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit);
                connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater);
                

                Or it will not work because the thread is not destroyed?

                J.HilkJ 1 Reply Last reply
                0
                • Cobra91151C Cobra91151

                  I use connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::deleteLater); but then I get warning: QThread: Destroyed while thread is still running.

                  So should I connection like this:

                  connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit);
                  connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater);
                  

                  Or it will not work because the thread is not destroyed?

                  J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by
                  #8

                  @Cobra91151 said in Memory leak using QThread issue:

                  So should I connection like this:

                  connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit);
                  connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater);
                  

                  Or it will not work because the thread is not destroyed?

                  No, this is exactly the correct way to do it.


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  Cobra91151C 1 Reply Last reply
                  0
                  • J.HilkJ J.Hilk

                    @Cobra91151 said in Memory leak using QThread issue:

                    So should I connection like this:

                    connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit);
                    connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater);
                    

                    Or it will not work because the thread is not destroyed?

                    No, this is exactly the correct way to do it.

                    Cobra91151C Offline
                    Cobra91151C Offline
                    Cobra91151
                    wrote on last edited by Cobra91151
                    #9

                    @J.Hilk

                    I have changed code to:

                     appCheckUpdate = new CheckUpdates();
                     appCheckUpdatesThread = new QThread();
                     appCheckUpdate->moveToThread(appCheckUpdatesThread);
                     connect(appCheckUpdatesThread, &QThread::started, appCheckUpdate, &CheckUpdates::checkUpdate);
                     connect(appCheckUpdate, &CheckUpdates::updateData, this, &Changelog::getUpdateData);
                     connect(appCheckUpdate, &CheckUpdates::networkError, this, &Changelog::changeLogUpdateError);
                     connect(appCheckUpdate, &CheckUpdates::localeError, this, &Changelog::updateLocaleError);
                     connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit);
                     connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater);
                     appCheckUpdatesThread->start();
                    

                    But the problem still exists, it leaks memory. So this - connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater); - deletes only appCheckUpdatesThread (QThread) object.

                    So should I also delete appCheckUpdate by calling delete appCheckUpdate?

                    J.HilkJ jsulmJ 2 Replies Last reply
                    0
                    • Cobra91151C Cobra91151

                      @J.Hilk

                      I have changed code to:

                       appCheckUpdate = new CheckUpdates();
                       appCheckUpdatesThread = new QThread();
                       appCheckUpdate->moveToThread(appCheckUpdatesThread);
                       connect(appCheckUpdatesThread, &QThread::started, appCheckUpdate, &CheckUpdates::checkUpdate);
                       connect(appCheckUpdate, &CheckUpdates::updateData, this, &Changelog::getUpdateData);
                       connect(appCheckUpdate, &CheckUpdates::networkError, this, &Changelog::changeLogUpdateError);
                       connect(appCheckUpdate, &CheckUpdates::localeError, this, &Changelog::updateLocaleError);
                       connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit);
                       connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater);
                       appCheckUpdatesThread->start();
                      

                      But the problem still exists, it leaks memory. So this - connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater); - deletes only appCheckUpdatesThread (QThread) object.

                      So should I also delete appCheckUpdate by calling delete appCheckUpdate?

                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #10

                      @Cobra91151
                      yes of course,
                      at the end of your threaded operation, you'll have to delete your QThread object and your Worker object, seperately.

                      In case you haven't seen it, heres an wiki-example


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      Cobra91151C 2 Replies Last reply
                      1
                      • J.HilkJ J.Hilk

                        @Cobra91151
                        yes of course,
                        at the end of your threaded operation, you'll have to delete your QThread object and your Worker object, seperately.

                        In case you haven't seen it, heres an wiki-example

                        Cobra91151C Offline
                        Cobra91151C Offline
                        Cobra91151
                        wrote on last edited by
                        #11

                        @J.Hilk

                        Thanks for the link. I will try it.

                        1 Reply Last reply
                        0
                        • Cobra91151C Cobra91151

                          @J.Hilk

                          I have changed code to:

                           appCheckUpdate = new CheckUpdates();
                           appCheckUpdatesThread = new QThread();
                           appCheckUpdate->moveToThread(appCheckUpdatesThread);
                           connect(appCheckUpdatesThread, &QThread::started, appCheckUpdate, &CheckUpdates::checkUpdate);
                           connect(appCheckUpdate, &CheckUpdates::updateData, this, &Changelog::getUpdateData);
                           connect(appCheckUpdate, &CheckUpdates::networkError, this, &Changelog::changeLogUpdateError);
                           connect(appCheckUpdate, &CheckUpdates::localeError, this, &Changelog::updateLocaleError);
                           connect(appCheckUpdate, &CheckUpdates::finished, appCheckUpdatesThread, &QThread::quit);
                           connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater);
                           appCheckUpdatesThread->start();
                          

                          But the problem still exists, it leaks memory. So this - connect(appCheckUpdatesThread, &CheckUpdates::destroyed, appCheckUpdatesThread, &QThread::deleteLater); - deletes only appCheckUpdatesThread (QThread) object.

                          So should I also delete appCheckUpdate by calling delete appCheckUpdate?

                          jsulmJ Offline
                          jsulmJ Offline
                          jsulm
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @Cobra91151 It should be:

                          connect(appCheckUpdatesThread, &QThread::finished, appCheckUpdatesThread, &QThread::deleteLater);
                          

                          In http://doc.qt.io/qt-5.8/qthread.html#finished
                          "This signal can be connected to QObject::deleteLater(), to free objects in that thread."

                          https://forum.qt.io/topic/113070/qt-code-of-conduct

                          1 Reply Last reply
                          2
                          • J.HilkJ J.Hilk

                            @Cobra91151
                            yes of course,
                            at the end of your threaded operation, you'll have to delete your QThread object and your Worker object, seperately.

                            In case you haven't seen it, heres an wiki-example

                            Cobra91151C Offline
                            Cobra91151C Offline
                            Cobra91151
                            wrote on last edited by
                            #13

                            @J.Hilk

                            Thank you. I have fixed the memory leak issue with changelog, but I also have the memory leak when I reload some WMI data during language change of my app. I will try to fix it and reply.

                            1 Reply Last reply
                            0
                            • Cobra91151C Offline
                              Cobra91151C Offline
                              Cobra91151
                              wrote on last edited by Cobra91151
                              #14

                              Hi! I have some WMI memory leak issue.

                              Code:

                              //Initialization
                              IWbemLocator *pLocator = 0;
                              IWbemServices *pService = 0;
                              IEnumWbemClassObject* pEnumerator = NULL;
                              IWbemClassObject *pclsObj = NULL;
                              
                              while (pEnumerator)
                              {
                                   hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
                              
                                    VARIANT processName;
                                    pclsObj->Get(L"Name", 0, &processName, 0, 0);
                                    QString userProcessName;
                                    userProcessName = QString::fromWCharArray(processName.bstrVal);
                                     
                                    emit testData(userProcessName);
                                    VariantClear(&processName);
                              }
                              
                              //Cleanup
                               pService->Release();
                               pLocator->Release();
                               //pEnumerator->Release(); - Clang Static Analyzer displays issue - called C++ object pointer is null
                               //pclsObj->Release(); - Clang Static Analyzer displays issue - called C++ object pointer is null
                              

                              Every time I change language in my app it takes 1 - 5 MB RAM. How to fix this issue? Thanks in advance.

                              A 1 Reply Last reply
                              0
                              • Cobra91151C Cobra91151

                                Hi! I have some WMI memory leak issue.

                                Code:

                                //Initialization
                                IWbemLocator *pLocator = 0;
                                IWbemServices *pService = 0;
                                IEnumWbemClassObject* pEnumerator = NULL;
                                IWbemClassObject *pclsObj = NULL;
                                
                                while (pEnumerator)
                                {
                                     hres = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
                                
                                      VARIANT processName;
                                      pclsObj->Get(L"Name", 0, &processName, 0, 0);
                                      QString userProcessName;
                                      userProcessName = QString::fromWCharArray(processName.bstrVal);
                                       
                                      emit testData(userProcessName);
                                      VariantClear(&processName);
                                }
                                
                                //Cleanup
                                 pService->Release();
                                 pLocator->Release();
                                 //pEnumerator->Release(); - Clang Static Analyzer displays issue - called C++ object pointer is null
                                 //pclsObj->Release(); - Clang Static Analyzer displays issue - called C++ object pointer is null
                                

                                Every time I change language in my app it takes 1 - 5 MB RAM. How to fix this issue? Thanks in advance.

                                A Offline
                                A Offline
                                ambershark
                                wrote on last edited by
                                #15

                                @Cobra91151 This isn't Qt code.. You should probably post this question on a win32 API message board.

                                Also are you sure it's actually leaking? Just because the size of memory for your running application grows does not mean it's leaking. You need something like valgrind to test for leaks on exit.

                                My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

                                Cobra91151C A 2 Replies Last reply
                                1
                                • A ambershark

                                  @Cobra91151 This isn't Qt code.. You should probably post this question on a win32 API message board.

                                  Also are you sure it's actually leaking? Just because the size of memory for your running application grows does not mean it's leaking. You need something like valgrind to test for leaks on exit.

                                  Cobra91151C Offline
                                  Cobra91151C Offline
                                  Cobra91151
                                  wrote on last edited by Cobra91151
                                  #16

                                  @ambershark

                                  I have checked it in Task Manager. For example, my app takes 25 MB RAM, when changing languages it grows to 30 MB and 35, 40... and never release it. So should I consider this as not a leak?

                                  1 Reply Last reply
                                  0
                                  • SGaistS Offline
                                    SGaistS Offline
                                    SGaist
                                    Lifetime Qt Champion
                                    wrote on last edited by
                                    #17

                                    What do you mean by changing languages ? What do you do to make that happen ?

                                    Interested in AI ? www.idiap.ch
                                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                    Cobra91151C 1 Reply Last reply
                                    0
                                    • SGaistS SGaist

                                      What do you mean by changing languages ? What do you do to make that happen ?

                                      Cobra91151C Offline
                                      Cobra91151C Offline
                                      Cobra91151
                                      wrote on last edited by Cobra91151
                                      #18

                                      @SGaist

                                      I have all WMI data in QTreeWidgetItems (QTreeWidget). I have two columns:
                                      1 - Property
                                      2 - Data

                                      Property and data I get from a worker class which connected with signals and slots to thread. So to change property to another language I call clear function on QTreeWidget to delete all property and data, then I call function which connects worker to thread and get this data as QTreeWidgetItems in chosen (translated) language.

                                      1 Reply Last reply
                                      0
                                      • SGaistS Offline
                                        SGaistS Offline
                                        SGaist
                                        Lifetime Qt Champion
                                        wrote on last edited by
                                        #19

                                        Are you loading any language file in order to provide translations ?

                                        Interested in AI ? www.idiap.ch
                                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                        Cobra91151C 1 Reply Last reply
                                        0
                                        • SGaistS SGaist

                                          Are you loading any language file in order to provide translations ?

                                          Cobra91151C Offline
                                          Cobra91151C Offline
                                          Cobra91151
                                          wrote on last edited by Cobra91151
                                          #20

                                          @SGaist

                                          Yes, but when QComboBox index changes I call this function to load appropriate translation file:

                                          Some code:

                                          appTranslator = new QTranslator(this);
                                          qApp->removeTranslator(appTranslator);
                                          appTranslator->load(":Localization/Test_ru.qm");
                                           qApp->installTranslator(appTranslator);
                                          

                                          and when apply button is clicked I retranslate string and reload WMI data using my loadTraslatedText function

                                          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