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. Troubled by memory leak problem in QNetworkAccessManager !!!
Forum Updated to NodeBB v4.3 + New Features

Troubled by memory leak problem in QNetworkAccessManager !!!

Scheduled Pinned Locked Moved General and Desktop
qnetworkaccessmmemory leakqnetwork
3 Posts 2 Posters 2.8k 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
    sczhengyabin
    wrote on last edited by
    #1

    Hi,
    I am recently using Qt to create a network module which involved Http requests.
    I found a very disturbing problem when I used the QNetworkAccessManager and related classes.
    For convienience, I simplified my code to example below. Each time I click the button, the Virtual Memory just keep growing up. I browsed other topics in forum, where I cannot find the reason. I hope you guys can help me on this.
    Thanks.

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QDebug>

    MainWindow::MainWindow(QWidget parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);
    manager = new QNetworkAccessManager;
    connect(manager, SIGNAL(finished(QNetworkReply
    )), this, SLOT(onfinished(QNetworkReply*)));
    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void MainWindow::onfinished(QNetworkReply *reply)
    {
    qDebug() << reply->readAll();
    reply->abort();
    reply->close();
    reply->deleteLater();
    }

    void MainWindow::on_pushButtonLogin_clicked()
    {
    isNeedVcode();
    }

    int MainWindow::isNeedVcode()
    {
    QNetworkRequest request;
    //QString strurl = QString("http://www.baidu.com");
    QString strurl = QString("http://check.ptlogin2.qq.com/check?&uin=870603663");
    request.setUrl(QUrl(strurl));
    //
    request.setRawHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/6.0)");
    //
    manager->get(request);

    return 0;
    

    }

    1 Reply Last reply
    0
    • M Offline
      M Offline
      mchinand
      wrote on last edited by
      #2

      Are you getting your qDebug() output from the onfinished() slot? If not, I'm guessing it's because your connect statement is incorrect; your data types of your SIGNAL and SLOT do not match (QNetworkReply vs. QNetworkReply*). Since your onfinished() slot wouldn't ever be called because of the bad connect statement, your QNetworkReply never gets deleted either.

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

        It's a mistake when I copy the code from other place.

        Here are the exact code below that I just write for this network test.
        The bigger the count of request sent in a loop, the more consumed virtual memory of this program.
        And after finished all of these http requests, the Virtual Memory of this program did not reduce.
        However, when I add a qWait(1) between every request, the memory will not goes up when the number of sent requests grows. But the memory still doesn't go down when I delete everything I used to access network.
        It seems when concurrently create and send a large amount of http requests through QNetworkAccessManager, the memory leakage will happen.

        //Header**
        #ifndef NETWORK_H
        #define NETWORK_H

        #include <QObject>
        #include <QNetworkAccessManager>
        #include <QNetworkRequest>
        #include <QNetworkReply>
        #include <QUrl>
        #include <QTest>

        class NetWork : public QObject
        {
        Q_OBJECT
        private:
        explicit NetWork(QObject *parent = 0);

        public:
        static NetWork *Instance();

        void Post(const QUrl &url, const QByteArray content);
        void Get(const QUrl &url);
        
        void Clean();
        void Print();
        QNetworkAccessManager *Manager();
        

        signals:

        public slots:
        void SlotPostFinished();
        void SlotCountDestroyed();

        private:
        static NetWork *_network;
        QNetworkAccessManager *_manager;

        public:
        qint32 _countOk, _countError, _countSent, _countDestroyed;
        };

        class UnitTest_Network : public QObject{
        Q_OBJECT
        public:
        explicit UnitTest_Network(QObject *parent = 0);

        private slots:
        void test10ps();
        void test10ps_data();
        };

        #endif // NETWORK_H

        //CPP
        #include "network.h"

        NetWork::NetWork(QObject *parent) :
        QObject(parent)
        {
        _manager = new QNetworkAccessManager(this);
        }

        NetWork *NetWork::_network = NULL;
        NetWork *NetWork::Instance()
        {
        if(_network == NULL){
        _network = new NetWork();
        }
        return _network;
        }

        void NetWork::Post(const QUrl &url, const QByteArray content)
        {
        QNetworkRequest request(url);

        request.setRawHeader("Content-Type", "application/json");
        
        QNetworkReply *reply = _manager->post(request, content);
        
        connect(reply, SIGNAL(finished()), 
        		this, SLOT(SlotPostFinished()));
        connect(reply, SIGNAL(destroyed()),
        		this, SLOT(SlotCountDestroyed()));
        

        }

        void NetWork::Get(const QUrl &url)
        {
        QNetworkRequest request(url);

        request.setRawHeader("Content-Type", "application/json");
        
        QNetworkReply *reply = _manager->get(request);
        
        connect(reply, SIGNAL(finished()), 
        		this, SLOT(SlotPostFinished()), 
        		Qt::DirectConnection);
        connect(reply, SIGNAL(destroyed()),
        		this, SLOT(SlotCountDestroyed()));
        

        }

        void NetWork::Clean()
        {
        _countOk = 0;
        _countError = 0;
        _countSent = 0;
        _countDestroyed = 0;
        }

        void NetWork::Print()
        {
        qDebug("10 ps:\t Sent = %d, Ok = %d, Error = %d, Destroyed = %d",
        _countSent, _countOk, _countError, _countDestroyed);
        qApp->processEvents();
        }

        QNetworkAccessManager *NetWork::Manager()
        {
        return _manager;
        }

        void NetWork::SlotPostFinished()
        {
        QNetworkReply reply = (QNetworkReply)sender();
        qint32 statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
        if(!reply->error()){
        _countOk++;
        }
        else{
        _countError++;
        }
        reply->readAll();
        reply->abort();
        reply->close();
        reply->deleteLater();
        }

        void NetWork::SlotCountDestroyed()
        {
        _countDestroyed++;
        }

        void UnitTest_Network::test10ps()
        {

        }

        void UnitTest_Network::test10ps_data()
        {
        QTest::addColumn<qint32>("hehe");
        NetWork::Instance()->Clean();
        qDebug("Test 10 ps ...");

        qint32 count = 500;
        qDebug("Starting ...");
        QTest::qWait(1000);
        
        for(int j=0; j<10; j++){
        	for(int i=0; i<count; i++){
        		NetWork::Instance()->Post(QString("http://192.168.0.90/rest/Logs/"),
        								  QByteArray("{\"reserve\" : \"\", \"logTime\" : 1410865245827,  \"machineId\" : \"0023\", \"operationCode\" : \"x\", \"deviceNum\" : \"b\", \"deviceAttribute\" : \"5\",\"parameter\" :\"0624\",  \"checksum\" : -111,  \"serialNum\" : \"92bb\"}"));
        		NetWork::Instance()->_countSent++;
        

        // QTest::qWait(1);
        // qApp->processEvents();
        }
        qDebug("LOOP No.%d", j);
        }

        while(1){
        	if(NetWork::Instance()->_countSent == NetWork::Instance()->_countError + NetWork::Instance()->_countOk)
        		break;
        	NetWork::Instance()->Print();
        	QTest::qWait(5000);
        }
        
        qDebug("delete manager ...");
        QTest::qWait(5000);
        NetWork::Instance()->Manager()->deleteLater();	
        qDebug("wait ...");
        QTest::qWait(5000);
        qDebug("delete network ...");
        NetWork::Instance()->deleteLater();
        QTest::qWait(5000);
        qDebug("End ...");
        QTest::qWait(10000);
        

        }

        UnitTest_Network::UnitTest_Network(QObject *parent)
        {
        }

        QTEST_MAIN(UnitTest_Network)

        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