XMLHttp POST请求导致大量内存泄漏

时间:2016-09-02 05:51:39

标签: javascript ajax memory-leaks

如何避免XHR POST内存泄漏?我浏览了很多关于XHR内存泄漏的网页,但没有好的解决方案。我的问题几乎与this类似。该博客解释了问题,但没有解决方案。

我的问题: 我有一个Web应用程序,它连续向服务器发送日期(2Mb到80Mb),它将发出10到300个请求。这是POST请求。对于GET请求没有像这样的大问题。

我该如何解决这个问题? 循环参考,范围,更接近等我尝试但没有成功。 我尝试使用delete关键字进行readystate更改,删除以前的xhr对象,尝试重用xhr,xhr引用null,更改编码模式等

这是示例代码。这是我需要的功能

 var base_string =  "ABCDEFGHIJKLMNOPQUST01234567890!@#$%^&:ABCDEFGHIJKLMNOPQUST01234567890!@#$%^&ABCDEFGHIJKLMNOPQUST01234567890!@#$%^&";
            base_string += base_string;  
            base_string += base_string; 
            base_string += base_string; 
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string; 
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string; 
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string;  
            base_string += base_string;  
            this.sampleData = base_string;
            var dataToSend = this.sampleData.substring( 0, 2000000 );



           this.xhr = [];
           this.xhr[0] = new XMLHttpRequest();
           function sendRequest (){
               var Self = this;
               Self.xhr[0].onload = function (test) {
                   sendRequest ();
               };

               Self.xhr[0].open("POST", "http://localhost/upload.php" + "?n=" +  Math.random(), true);
               Self.xhr[0].send(dataToSend);
           }
           sendRequest ();

如何在没有内存泄漏的情况下实现此目的?

4 个答案:

答案 0 :(得分:2)

清理代码 - 这应该做同样的事情,没有Self和数组的奇怪和毫无意义的使用......它还重新初始化xhr

我已经改为为上传加载事件添加一个监听器 - 这里的快速测试似乎没有泄漏(似乎)

name

答案 1 :(得分:2)

连续+请求大小+请求数量。我认为你不应该在这种情况下使用XHR。也许WebRTC,长轮询或Web套接字。即使您找到以这种方式执行它的解决方法,也不会扩展。

答案 2 :(得分:1)

对于您发送的每个请求,您都添加了一个新的onload处理程序。

Self.xhr[0].onload = function (test) {
    sendRequest ();
};

此处不会删除旧处理程序并保留在内存中。垃圾收集器将无法释放内存。

在你的情况下,你只需要一个eventlistener,所以我建议你把这个监听器的附件移出sendRequest函数,就像这样,内存泄漏就应该消失了。

this.xhr = [];
this.xhr[0] = new XMLHttpRequest();
xhr[0].onload = function (test) {
    sendRequest ();
};
function sendRequest (){
    xhr[0].open("POST", "http://localhost/upload.php" + "?n=" +  Math.random(), true);
    xhr[0].send(dataToSend);
}
sendRequest (); 

编辑:版本2

我尝试过另一个产生更好效果的版本。在我的设置中,内存永远不会超过2.6G。它是Jaromandas工作的衍生物。 它基本上是他的版本,添加了removeEventHandlerdelete

function sendRequest (){
function run(e){
  xhr.upload.removeEventListener('load',run)
  sendRequest()
}
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener('load', run);
xhr.open("POST", "http://localhost:2345/" + "?n=" +  Math.random(), true);
xhr.send(dataToSend);
delete xhr
}
sendRequest ();

答案 3 :(得分:1)

尝试更新的现代方法,使用fetch ...?

let url = '/upload.php'
let myInit = {
    method: 'post',
    cache: 'no-store',
    body: new ArrayBuffer(2000000)
}

function sendRequest() {
    return fetch(url, myInit)
        .then(res => res.blob())
        .then(sendRequest)
}

sendRequest()