Solved How to use QNetworkAccessManager without leaking memory.
-
I replace you
sleep
with timer, does this change anything?#include "form.h" #include "ui_form.h" #include <QtNetwork> #include <QUrl> #include "QProgressDialog" #include "QMessageBox" #include "QTextBlock" #include "qcoreapplication.h" Form::Form(QWidget *parent) : QWidget(parent), ui(new Ui::Form) { ui->setupUi(this); #ifndef QT_NO_SSL connect(&qnam, &QNetworkAccessManager::sslErrors, this, &Form::sslErrors); #endif } Form::~Form() { delete ui; } void Form::on_pushButton_clicked() { ui->pushButton->hide(); startRequest(); } void Form::startRequest() { qnam.clearAccessCache(); reply = qnam.get(QNetworkRequest(url)); connect(reply, &QNetworkReply::finished, this, &Form::httpFinished); } void Form::httpFinished() { reply->deleteLater(); QTimer::singleShot(1000, this, &Form::startRequest); }
-
@Bonnie Unfortunately not.
QNetworkAccessManager qnam; QNetworkReply *reply; void Form::startRequest() { qnam.clearAccessCache(); reply = qnam.get(QNetworkRequest(QUrl("www.microsoft.com"))); connect(reply, &QNetworkReply::finished, this, &Form::httpFinished); } void Form::httpFinished() { disconnect(reply, &QNetworkReply::finished, this, &Form::httpFinished); reply->deleteLater(); QTimer::singleShot(1, this, &Form::startRequest); }
This sums the core code up..
If someone plans to use it as ddos code it will probably flood your own memory up instead. -
@Q139 Actually, I don't get a increasing memory while testing the last and the previous code of yours.
I wonder if it needs to be tested with a url that have a big size of reply data...
I'm using Qt 5.12 though... -
@Q139 said in How to use QNetworkAccessManager without leaking memory.:
If someone plans to use it as ddos code it will probably flood your own memory up instead.
No it won't - there is no leak in this code anymore.
The disconnect() is not needed though. -
I still get leak.
Could you check if application output gives SSL error while connecting to https site?
I also had to install openSSL in addition to get it working, maybe it is related to that.
And while tested on ubuntu got no leak , but it had SSL errors in app output.
Got SSL for win7 and win10 from here, the lite edition, maybe that component causes problems. -
@Bonnie Used invalid url text , like "test" also and got leak.
-
Install openSSL on Windows 7 or 10 and see if the app below leaks memory.
Windows ssl libraries site
direct link to download-Win64 OpenSSL v1.1.1g Light -
Current solution to use QNetworkAcessManager 50 times:
I thought maybe using just once and deleting gives overhead.
This way it goes to ~100mb and back to ~20mb all the time, instead of gb+int qnamUses=0; QNetworkAccessManager *qnam=new QNetworkAccessManager; QNetworkReply *reply; void Form::startRequest() { qnamUses++; if(qnamUses>50){ qnam->deleteLater(); qnam=new QNetworkAccessManager; } reply = qnam->get(QNetworkRequest(QUrl("www.microsoft.com"))); connect(reply, &QNetworkReply::finished, this, &Form::httpFinished); } void Form::httpFinished() { // qnam.clearAccessCache(); //qnam->deleteLater(); reply->deleteLater(); QTimer::singleShot(0, this, &Form::startRequest); }
-
@Q139 said in How to use QNetworkAccessManager without leaking memory.:
qnam=new QNetworkAccessManager;
Why do you create QNetworkAccessManager instance for each request? One can handle many requests...
-
@jsulm For 50 requests , then schedule for deletion. to prevent memory usage growth.
Maybe i am using something incorrectly. -
You never reset qnamUses. Therefore after 51 requests, you recreate your qnam object for every request.
-
Reset was fixed in test.
Is there a way to use single instance of QNetworkAccessManager for 10k+ times without drastic memory usage growth? -
@Q139 said in How to use QNetworkAccessManager without leaking memory.:
I still get leak.
The Task manager is no tool to measure a memory leak!
Is there a way to use single instance of QNetworkAccessManager for 10k+ times without drastic memory usage growth?
Yes, simply use it.
-
@Christian-Ehrlicher It ends with app filling memory and crashing if simply using.
-
@Q139 I still don't have a valid reproducer for this behavior...
-
@Christian-Ehrlicher I tryed and it leaks on win 7 in vmware and win 10 native.
What version of Qt are you running? Did you also intall the openSSL?This produces problem in my tests. Only solution i find is to delete QNetworkAccessManager after some period and recreate it.
@Q139 said in How to use QNetworkAccessManager without leaking memory.:Install openSSL on Windows 7 or 10 and see if the app below leaks memory.
Windows ssl libraries site
direct link to download-Win64 OpenSSL v1.1.1g Light -
@Q139 said in How to use QNetworkAccessManager without leaking memory.:
Did you also intall the openSSL?
No need for ssl at all since your url ist http.
-
´Please update the wait time between two requests to 100ms and see if the problem still persists. Looks like there is a race condition when the same url is queried very fast. But can't see the main reason for it currently.
-
Using 100ms and variable urls solves it.
-
Helpful discussion for me ,thank eveyone
Same situation with Qt 5.14.2 Mingw on Windows7 and Qt5.9.9 on MacOSX