[英]How do I fix this Javascript Memory Leak
Here's the code: 这是代码:
function refreshContent(id) {
function imageLoaded(){
//get device div
var device_div = document.getElementById("device-" + id);
//remove old image, if there is one
if(device_div.hasChildNodes())
delete device_div.removeChild(device_div.lastChild);
device_div.appendChild(image);
var device_id = device_div.id.split("-")[1]; //divs are named "device-<something>"
window.setTimeout(refreshContent, 5000, device_id);
}
var image = new Image();
image.src = SERVER_BASE_URL + "/api/test/" + id + "/image/" + new Date().getTime();
image.addEventListener("load", imageLoaded);
}
Memory usage according to Chrome task manager quickly grows when this is running and doesn't when I disable it, so I know it's this portion of the code that's leaking. 根据Chrome任务管理器的运行情况,内存使用量会迅速增加,而禁用它时却不会增加,因此我知道这是泄漏的这部分代码。
Some ideas I have: 我有一些想法:
Nothing I've tried seems to make a difference. 我尝试过的一切似乎都无济于事。
You should remove the event listener as soon as it is invoked. 您应该在调用事件侦听器后立即将其删除。
function refreshContent(id) {
function imageLoaded(){
image.removeEventListener("load", imageLoaded);
//get device div
var device_div = document.getElementById("device-" + id);
//remove old image, if there is one
if(device_div.hasChildNodes())
delete device_div.removeChild(device_div.lastChild);
device_div.appendChild(image);
var device_id = device_div.id.split("-")[1]; //divs are named "device-<something>"
window.setTimeout(refreshContent, 5000, device_id);
}
var image = new Image();
image.src = SERVER_BASE_URL + "/api/test/" + id + "/image/" + new Date().getTime();
image.addEventListener("load", imageLoaded);
}
Forgetting to unregister an event listener is a very common cause of memory leak. 忘记注销事件监听器是内存泄漏的一个很常见的原因。
I'll just recap what I see here. 我将回顾一下我在这里看到的内容。 Each 5 seconds:
每5秒:
id
parameter is provided id
参数 imageLoaded
) is created, bound to the value of id
imageLoaded
),绑定到id
的值 imageLoaded
function instance imageLoaded
函数实例 I may be wrong, but it seems to me that they will hold one to each other tightly, and that they might not be garbage collected. 我可能错了,但是在我看来,它们将彼此紧紧地抱在一起,而且可能不会被垃圾回收。
So, just adding a line 因此,只需添加一行
image = null;
after 后
image.addEventListener("load", imageLoaded);
might solve the situation. 可能会解决这种情况。 So, you should end up with:
因此,您应该最终得到:
function refreshContent(id) {
function imageLoaded() {
//get device div
var device_div = document.getElementById("device-" + id);
//remove old image, if there is one
if (device_div.hasChildNodes())
delete device_div.removeChild(device_div.lastChild);
device_div.appendChild(image);
var device_id = device_div.id.split("-")[1]; //divs are named "device-<something>"
window.setTimeout(refreshContent, 5000, device_id);
}
var image = new Image();
image.src = SERVER_BASE_URL + "/api/test/" + id + "/image/" + new Date().getTime();
image.addEventListener("load", imageLoaded);
image = null;
}
Actually, this is a duplicate of Dispose an image object , but it might be that Pascal Le Merrer has a point in his answer. 实际上,这是Dispose一个图像对象的重复,但是可能Pascal Le Merrer的回答有道理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.