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 on QNetworkAccessManager
Forum Updated to NodeBB v4.3 + New Features

Memory Leak on QNetworkAccessManager

Scheduled Pinned Locked Moved Solved General and Desktop
15 Posts 6 Posters 4.5k 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.
  • Maickonn RichardM Offline
    Maickonn RichardM Offline
    Maickonn Richard
    wrote on last edited by
    #1

    Hello, first of all I would like to apologize for my English, I live in Brazil.

    I am having problems with possible Memory Leaks in the QNetworkAccessManager class. I did a lot of research and it seems that I was not the only one to notice such a problem.

    I do not know if it's the way I'm doing or if it is really a problem in class.

    I have created a function to get the HTML code of certain websites, however whenever this function is called, I notice a small increase in consumption in RAM. I've already tried using the deleteLater() function and several other ways, but to no avail. What else has worked so far is manually deleting the memory pointers, but there are still minor leaks.

    Here is the function I created:

    #include <QObject>
    #include <QString>
    #include <QNetworkAccessManager>
    #include <QNetworkRequest>
    #include <QNetworkReply>
    #include <QEventLoop>
    #include <QTimer>
    
    
    QString getHTML(QString url)
    {
        QNetworkAccessManager *manager = new QNetworkAccessManager();
        QNetworkRequest request;
        QNetworkReply *reply;
        QEventLoop *loop = new QEventLoop();
        QTimer *timeout = new QTimer();
    
        timeout->setSingleShot(true);
    
        request.setUrl(QUrl(url));
        request.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
        request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
    
        QObject::connect(manager, SIGNAL(finished(QNetworkReply*)), loop, SLOT(quit()));
        QObject::connect(timeout, SIGNAL(timeout()), loop, SLOT(quit()));
    
        reply = manager->get(request);
    
        timeout->start(10000);
        loop->exec();
    
        QString html = reply->readAll();
    
        delete reply;
        delete loop;
        delete timeout;
        delete manager;
    
        return html;
    }
    

    Follow the pictures during my tests:
    • On idle:
    0_1532625903949_idle.jpg

    • After 1 minute:
    0_1532625938913_after 1 minute.jpg

    • After 6 minutes:
    0_1532625990201_after 6 minutes.jpg

    • After 28 minutes:
    0_1532626052909_after 28 min.jpg

    I will also leave the link of my project as an example of the problem in GitHub. I am using the MingW 32bit compiler with Qt 5.11.1
    https://github.com/senjaxus/Memory-Leak-on-QNetworkAccessManager

    Thanks to everyone who can help find the problem.

    aha_1980A J.HilkJ 2 Replies Last reply
    0
    • Maickonn RichardM Maickonn Richard

      Hello, first of all I would like to apologize for my English, I live in Brazil.

      I am having problems with possible Memory Leaks in the QNetworkAccessManager class. I did a lot of research and it seems that I was not the only one to notice such a problem.

      I do not know if it's the way I'm doing or if it is really a problem in class.

      I have created a function to get the HTML code of certain websites, however whenever this function is called, I notice a small increase in consumption in RAM. I've already tried using the deleteLater() function and several other ways, but to no avail. What else has worked so far is manually deleting the memory pointers, but there are still minor leaks.

      Here is the function I created:

      #include <QObject>
      #include <QString>
      #include <QNetworkAccessManager>
      #include <QNetworkRequest>
      #include <QNetworkReply>
      #include <QEventLoop>
      #include <QTimer>
      
      
      QString getHTML(QString url)
      {
          QNetworkAccessManager *manager = new QNetworkAccessManager();
          QNetworkRequest request;
          QNetworkReply *reply;
          QEventLoop *loop = new QEventLoop();
          QTimer *timeout = new QTimer();
      
          timeout->setSingleShot(true);
      
          request.setUrl(QUrl(url));
          request.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
          request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
      
          QObject::connect(manager, SIGNAL(finished(QNetworkReply*)), loop, SLOT(quit()));
          QObject::connect(timeout, SIGNAL(timeout()), loop, SLOT(quit()));
      
          reply = manager->get(request);
      
          timeout->start(10000);
          loop->exec();
      
          QString html = reply->readAll();
      
          delete reply;
          delete loop;
          delete timeout;
          delete manager;
      
          return html;
      }
      

      Follow the pictures during my tests:
      • On idle:
      0_1532625903949_idle.jpg

      • After 1 minute:
      0_1532625938913_after 1 minute.jpg

      • After 6 minutes:
      0_1532625990201_after 6 minutes.jpg

      • After 28 minutes:
      0_1532626052909_after 28 min.jpg

      I will also leave the link of my project as an example of the problem in GitHub. I am using the MingW 32bit compiler with Qt 5.11.1
      https://github.com/senjaxus/Memory-Leak-on-QNetworkAccessManager

      Thanks to everyone who can help find the problem.

      aha_1980A Offline
      aha_1980A Offline
      aha_1980
      Lifetime Qt Champion
      wrote on last edited by
      #2

      HI @Maickonn-Richard,

      QObject::connect(manager, SIGNAL(finished(QNetworkReply*)), loop, SLOT(quit()));
      QObject::connect(timeout, SIGNAL(timeout()), loop, SLOT(quit()));
      
      reply = manager->get(request);
      
      timeout->start(10000);
      loop->exec();
      

      Why don't you use Signals and Slots like the where designed? Using local event loops is advanced stuff. I bet the effect you see is because of that.

      Qt has to stay free or it will die.

      Maickonn RichardM 1 Reply Last reply
      3
      • Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Apart from the really strange code construct - task manager is not a tool to measure the real memory footprint of an application and it really is not a tool to check for memory leaks...
        valgrind on linux does not find anything which looks like a memleak here.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        Maickonn RichardM 1 Reply Last reply
        4
        • aha_1980A aha_1980

          HI @Maickonn-Richard,

          QObject::connect(manager, SIGNAL(finished(QNetworkReply*)), loop, SLOT(quit()));
          QObject::connect(timeout, SIGNAL(timeout()), loop, SLOT(quit()));
          
          reply = manager->get(request);
          
          timeout->start(10000);
          loop->exec();
          

          Why don't you use Signals and Slots like the where designed? Using local event loops is advanced stuff. I bet the effect you see is because of that.

          Maickonn RichardM Offline
          Maickonn RichardM Offline
          Maickonn Richard
          wrote on last edited by
          #4

          Hi @aha_1980 .

          I did it this way because the QNetworkAccessManager is asynchronous. I need to get it to wait for finalization or receive a timeout after a certain time, in the example case, 10 seconds.

          Could guide me if there's a better way to do this?

          aha_1980A 1 Reply Last reply
          0
          • Christian EhrlicherC Christian Ehrlicher

            Apart from the really strange code construct - task manager is not a tool to measure the real memory footprint of an application and it really is not a tool to check for memory leaks...
            valgrind on linux does not find anything which looks like a memleak here.

            Maickonn RichardM Offline
            Maickonn RichardM Offline
            Maickonn Richard
            wrote on last edited by
            #5

            @Christian-Ehrlicher

            Really the Windows task manager is not the best tool to check this problem. But I did not need another tool to identify that there is a leak, if there is one. It is very strange to see the program consuming RAM this way, this in the long run can be disastrous.

            1 Reply Last reply
            0
            • Maickonn RichardM Maickonn Richard

              Hi @aha_1980 .

              I did it this way because the QNetworkAccessManager is asynchronous. I need to get it to wait for finalization or receive a timeout after a certain time, in the example case, 10 seconds.

              Could guide me if there's a better way to do this?

              aha_1980A Offline
              aha_1980A Offline
              aha_1980
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @Maickonn-Richard

              I'd use a QTimer with 10 seconds timeout. When timer slot is fired, check if the request is finished, otherwise abort it.

              Am I missing something?

              Qt has to stay free or it will die.

              Maickonn RichardM 1 Reply Last reply
              2
              • aha_1980A aha_1980

                @Maickonn-Richard

                I'd use a QTimer with 10 seconds timeout. When timer slot is fired, check if the request is finished, otherwise abort it.

                Am I missing something?

                Maickonn RichardM Offline
                Maickonn RichardM Offline
                Maickonn Richard
                wrote on last edited by
                #7

                @aha_1980

                True, I had forgotten that part. I'll do this and see if the problem continues.

                1 Reply Last reply
                0
                • Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  @Maickonn-Richard said in Memory Leak on QNetworkAccessManager:

                  Really the Windows task manager is not the best tool

                  It's not even a tool to catch such kind of errors in any way. It may be a hint but nothing more... and since valgrind (which is a tool to catch exactly such kind of problems) does not show anything... but do whatever you like.

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  Maickonn RichardM 1 Reply Last reply
                  2
                  • Christian EhrlicherC Christian Ehrlicher

                    @Maickonn-Richard said in Memory Leak on QNetworkAccessManager:

                    Really the Windows task manager is not the best tool

                    It's not even a tool to catch such kind of errors in any way. It may be a hint but nothing more... and since valgrind (which is a tool to catch exactly such kind of problems) does not show anything... but do whatever you like.

                    Maickonn RichardM Offline
                    Maickonn RichardM Offline
                    Maickonn Richard
                    wrote on last edited by
                    #9

                    @Christian-Ehrlicher

                    I thank you very much for your help with Valgrind! unfortunately currently I can not access this tool.

                    1 Reply Last reply
                    0
                    • Maickonn RichardM Maickonn Richard

                      Hello, first of all I would like to apologize for my English, I live in Brazil.

                      I am having problems with possible Memory Leaks in the QNetworkAccessManager class. I did a lot of research and it seems that I was not the only one to notice such a problem.

                      I do not know if it's the way I'm doing or if it is really a problem in class.

                      I have created a function to get the HTML code of certain websites, however whenever this function is called, I notice a small increase in consumption in RAM. I've already tried using the deleteLater() function and several other ways, but to no avail. What else has worked so far is manually deleting the memory pointers, but there are still minor leaks.

                      Here is the function I created:

                      #include <QObject>
                      #include <QString>
                      #include <QNetworkAccessManager>
                      #include <QNetworkRequest>
                      #include <QNetworkReply>
                      #include <QEventLoop>
                      #include <QTimer>
                      
                      
                      QString getHTML(QString url)
                      {
                          QNetworkAccessManager *manager = new QNetworkAccessManager();
                          QNetworkRequest request;
                          QNetworkReply *reply;
                          QEventLoop *loop = new QEventLoop();
                          QTimer *timeout = new QTimer();
                      
                          timeout->setSingleShot(true);
                      
                          request.setUrl(QUrl(url));
                          request.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
                          request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
                      
                          QObject::connect(manager, SIGNAL(finished(QNetworkReply*)), loop, SLOT(quit()));
                          QObject::connect(timeout, SIGNAL(timeout()), loop, SLOT(quit()));
                      
                          reply = manager->get(request);
                      
                          timeout->start(10000);
                          loop->exec();
                      
                          QString html = reply->readAll();
                      
                          delete reply;
                          delete loop;
                          delete timeout;
                          delete manager;
                      
                          return html;
                      }
                      

                      Follow the pictures during my tests:
                      • On idle:
                      0_1532625903949_idle.jpg

                      • After 1 minute:
                      0_1532625938913_after 1 minute.jpg

                      • After 6 minutes:
                      0_1532625990201_after 6 minutes.jpg

                      • After 28 minutes:
                      0_1532626052909_after 28 min.jpg

                      I will also leave the link of my project as an example of the problem in GitHub. I am using the MingW 32bit compiler with Qt 5.11.1
                      https://github.com/senjaxus/Memory-Leak-on-QNetworkAccessManager

                      Thanks to everyone who can help find the problem.

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

                      @Maickonn-Richard

                      If I may,

                      this is one way, how you can make use of the assynchon function:

                      QString getHTML(QString url)
                      {
                          QNetworkRequest request;
                          request.setUrl(QUrl(url));
                          request.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
                          request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
                          
                      	QNetworkAccessManager *manager = new QNetworkAccessManager(this);
                      	connect(manager, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply){
                      		if(reply.error() == QNetworkReply::NoError)
                      			emit htmlRead(QString(reply->readAll());
                      		else
                      			emit htmlError(reply->error());
                                      manager->deleteLater();
                                      reply->deleteLater();
                      	});
                      	
                      	manager->get(request);
                      	
                      	QTimer *timeout = new QTimer(this);
                              timeout->start(10000);
                      	connect(timeout &QTimer::timeout, manager, [=]{
                      		emit htmlTimeout();
                      		manager->deleteLater();
                      		timeout->deleteLater();
                      	});
                      	
                      	connect(manager, &QNetworkAccessManager::finished, timeout, QTimer::deleteLater);
                      }
                      

                      You'll have to create slots that connect to the signals void htmlTimeout() , void htmlError(QNetworkReply::NetworkError) and void htmlRead(QString) and proceed from there.

                      This should work, but it's untested.


                      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.

                      aha_1980A 1 Reply Last reply
                      4
                      • J.HilkJ J.Hilk

                        @Maickonn-Richard

                        If I may,

                        this is one way, how you can make use of the assynchon function:

                        QString getHTML(QString url)
                        {
                            QNetworkRequest request;
                            request.setUrl(QUrl(url));
                            request.setRawHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36");
                            request.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
                            
                        	QNetworkAccessManager *manager = new QNetworkAccessManager(this);
                        	connect(manager, &QNetworkAccessManager::finished, this, [=](QNetworkReply *reply){
                        		if(reply.error() == QNetworkReply::NoError)
                        			emit htmlRead(QString(reply->readAll());
                        		else
                        			emit htmlError(reply->error());
                                        manager->deleteLater();
                                        reply->deleteLater();
                        	});
                        	
                        	manager->get(request);
                        	
                        	QTimer *timeout = new QTimer(this);
                                timeout->start(10000);
                        	connect(timeout &QTimer::timeout, manager, [=]{
                        		emit htmlTimeout();
                        		manager->deleteLater();
                        		timeout->deleteLater();
                        	});
                        	
                        	connect(manager, &QNetworkAccessManager::finished, timeout, QTimer::deleteLater);
                        }
                        

                        You'll have to create slots that connect to the signals void htmlTimeout() , void htmlError(QNetworkReply::NetworkError) and void htmlRead(QString) and proceed from there.

                        This should work, but it's untested.

                        aha_1980A Offline
                        aha_1980A Offline
                        aha_1980
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @J.Hilk very nice example!

                        And it perfectly shows how well signals works together with lambdas...

                        Qt has to stay free or it will die.

                        J.HilkJ M 2 Replies Last reply
                        1
                        • aha_1980A aha_1980

                          @J.Hilk very nice example!

                          And it perfectly shows how well signals works together with lambdas...

                          J.HilkJ Online
                          J.HilkJ Online
                          J.Hilk
                          Moderators
                          wrote on last edited by
                          #12

                          @aha_1980
                          thanks, sadly I leaked the QNetworkReply *reply in the example x).
                          Fixed 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.

                          1 Reply Last reply
                          4
                          • Maickonn RichardM Offline
                            Maickonn RichardM Offline
                            Maickonn Richard
                            wrote on last edited by
                            #13

                            Well guys, after leaving the software running for a long period with the code I posted, I noticed that the consumption of RAM stabilizes. That is, leaks are not happening.

                            I thank all who cooperated, the help of you all were immense, you gave me a number of alternative ways in which I had not considered before.

                            A big hug to everyone!

                            1 Reply Last reply
                            2
                            • aha_1980A aha_1980

                              @J.Hilk very nice example!

                              And it perfectly shows how well signals works together with lambdas...

                              M Offline
                              M Offline
                              May May
                              wrote on last edited by
                              #14

                              @aha_1980 Can you explane it. I have same problem with method PUT. Thank you so much!

                              jsulmJ 1 Reply Last reply
                              0
                              • M May May

                                @aha_1980 Can you explane it. I have same problem with method PUT. Thank you so much!

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

                                @May-May Hi!
                                Explain what?

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

                                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