[英]QML Memory leak sending XMLHttpRequest
创建XMLHttpRequest
的new
实例并调用send()
会导致垃圾收集器无法清除 memory 的使用,也无法清除gc()
。 在 object 上调用delete
也不会清除 memory。
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
visible: true
width: 640
height: 480
Component.onCompleted: {
for(var i = 0; i < 100000; i++) {
console.log("Send request " + i)
var xhttp = new XMLHttpRequest
xhttp.open('get', 'someurl')
xhttp.send()
delete xhttp
}
gc() //why won't this clean the instances of XMLHttpRequest???
}
}
如果我从不调用xhttp.send()
那么我没有任何 memory 泄漏。 垃圾收集开始了,因为没有引用var xhttp
并且 memory 被释放。 我想也许垃圾收集器没有触发,但gc()
也不会清除 memory 。
这个 MRE 将运行 100,000 次迭代,并在 memory 中保存大约 500MB。 这可以通过更改为i < 1000000
轻松容纳 5.0GB。
如何修复此 memory 泄漏并释放 memory?
类似问题的参考: QTBUG-43005(无解析) QTBUG-50231(无解析)
现在记录在QTBUG-83857
在这里,持有 2.0GB 的 memory。 它保持了将近 4 个小时,直到我终止了该程序。 当我关闭应用程序时,大约 60 秒后,整个 2GB memory 被释放
尝试使用 QNetworkAccessManager class
//main.qml
MyClass {
id: myNetworkClass
Component.onCompleted: {
for(var i = 0; i < 10000; i++) {
myNetworkClass.doDownload()
}
}
}
//myclass.h
#ifndef MYCLASS_H
#define MYCLASS_H
#include <QObject>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QDebug>
class MyClass : public QObject
{
Q_OBJECT
public:
explicit MyClass(QObject *parent = 0):QObject(){
manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(replyFinished(QNetworkReply*)));
}
public:
Q_INVOKABLE void doDownload() {
manager->get(QNetworkRequest(QUrl("https://esi.evetech.net/latest/characters/93610700")));
}
public slots:
void replyFinished(QNetworkReply *reply) {};
private:
QNetworkAccessManager *manager;
int count = 0;
};
#endif // MYCLASS_H
根据 htop 的说法,不幸的是,这也保留了 memory 并且没有释放它。
编辑
Create a new controlling class in C++ to handle your web requests and then set a root context property or register the type in QML and use the C++ api instead.
这是 go 的最简单方法:
在 myclass.cpp 中,您使用这种类型的代码以及适当的处理程序(replyFinished)创建一个方法
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
connect(manager, &QNetworkAccessManager::finished,
this, &MyClass::replyFinished);
manager->get(QNetworkRequest(QUrl("http://qt-project.org")));
--
qmlRegisterType<MyClass>("MyClass", 1,0, "MyClass");
--
并在您的 QML 文件中执行
import MyClass 1.0
Window {
MyClass {
id: myNetworkClass
}
function doLookup() { myNetworkClass.myCustomMethod(); }
}
这将为您提供一种稳定的方法来避免因运行本机 javascript 环境而导致的 QML 问题,该环境在强类型框架上是异步且弱类型的...
祝你好运!
原来的
首先,通过创建请求而不保存对创建的 object 的引用,您将挂起 object 引用...
在 Window 的属性中保留所有 XMLHttpRequest 对象的数组
Window
{
property var requests: []
// ...
Timer {
onTriggered: {
// add request to array
requests.push(xhttp);
}
}
}
然后也许开始删除数组中的对象......
var xhttp = requests.unshift()
xhttp.destroy()
但真正的问题是每隔 50 毫秒发送 http 请求
那是 ummm 每秒 20 个或 1200 个/分钟的请求
您可能需要调整代码以在前一个完成后发送请求..或将间隔设置为更高的值
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.