所有
我正在努力实现一个彗星JS库。现在我正在跟踪响应文本的大小,并在块到达时返回新部分。这为我的回调提供了新数据,但这是一个非常明显的内存泄漏。有没有办法强制关闭XMLHttpRequest对象或定期重置responseText的内容?
request.multi = function(type, handler, url, querystring){
querystring = (querystring == undefined) ? null: querystring;
var response = "";
var handle = makeRequestHandle();
handle.multipart = true;
handle.open(type, url, true);
handle.onreadystatechange = function(){
var return_val;
if(handle.readyState == 4){
m_log.debug("Conection died");
}else if(handle.readyState == 3){
return_val = handle.responseText.substring(response.length);
response = handle.responseText;
handler(return_val);
}else{
m_log.debug("readyState %s", handle.readyState);
}
};
handle.send(querystring);
}
答案 0 :(得分:0)
你是对的,只要请求处于活动状态,并且你的处理程序使用它,你就会在内存中的某处积累数据。
我说'某处',因为套接字数据会通过几个软件层。只要您的XHR正在进行中,您的运行时(浏览器或js运行时)将继续接收。它必须对内容执行解码(例如(un)gzip),并且可能解码传输编码(如果它是长时间连接,则可能是“chunked”)。
无论您是访问还是设置属性,都有一个包含(增长)有效负载的基础增长缓冲区。
至少在Chrome上,XMLHttpRequest.prototype.responseText
仅定义为getter属性。设置它(例如使用xhr.responseText = ''
将对底层缓冲区没有影响。内存将继续增长
// you can verify
var xhr = new XMLHttpRequest();
Console.log(Object.getOwnPropertyDescriptor(x.__proto__, "response"))
// I get
{... get: function () {...}, set: undefined }
对于xhr有效载荷{(1}}(对于blob)和xhr.response
,您可能拥有的其他“视图”也是如此。
使连接内存“重置”而不丢失消息的最可靠方法是在旧的ajax请求仍处于活动状态时启动新的ajax请求,并在旧的ajax请求收到完整的最后一条消息后切换到新的ajax请求。虽然两者都处于活动状态,但必须忽略新流上的数据,直到它们处于“同步”状态。
Memory efficient message chunk processing using a XMLHttpRequest
这当然假设流上收到的数据是相同的,或者有一些方法可以唯一地识别进入的消息,使两个流“对齐”。
曾经有过这样的内容类型,可以指示客户端在收到特定字符串时重置其响应。
它专为流媒体网络摄像头图像而设计,有一段时间被彗星滥用,并且有点像你想要的那样,但它的支持至少从Firefox和Chrome中删除了。众所周知,IE从一开始就不受其支持,所以今天也许如此。
xhr.responseXML
Content-type: multipart/x-mixed-replace;boundary=<randomstringhere>
不太可能出现在您的应用程序消息中。在每个消息“推”服务器之间,您插入<randomstringhere>
。浏览器会自动重置每个边界的<randomstringhere>
。
该问题的一个问题是,在浏览器收到下一个消息之前,您必须处理边界内的所有消息。所以至少对于AJAX来说这很有趣。
responseText
在问题中给出的示例中,responseText用于获取完整的有效负载。在x.response
通话之前,可以设置
send()
,然后在进程回调中,handle.responseType = "text"
将仅包含自上次调用处理程序以来的新信息。
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/response
然而,有可能整个有效载荷仍然可以通过handle.response
获得,因此这不足以解决内存失控问题。