[英]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.