Javascript 为什么我的svg节点在IE中泄漏内存

Javascript 为什么我的svg节点在IE中泄漏内存,javascript,internet-explorer,memory-leaks,svg,d3.js,Javascript,Internet Explorer,Memory Leaks,Svg,D3.js,背景:受D3内存使用的启发,我决定深入研究它到底是如何工作的,很快我就发现了 为了与D3所做的任何其他事情隔离开来,我首先尝试了基本的SVG案例,即每秒添加/删除1000个圆圈: var计数=1000; var svg=document.createElements(“http://www.w3.org/2000/svg“,“svg”); setAttribute('width','800'); setAttribute('height','800'); document.body.append

背景:受D3内存使用的启发,我决定深入研究它到底是如何工作的,很快我就发现了

为了与D3所做的任何其他事情隔离开来,我首先尝试了基本的SVG案例,即每秒添加/删除1000个圆圈:

var计数=1000;
var svg=document.createElements(“http://www.w3.org/2000/svg“,“svg”);
setAttribute('width','800');
setAttribute('height','800');
document.body.appendChild(svg);
函数更新(){
//删除现有的圆圈
var circles=svg.querySelectorAll(“圆”)
对于(var i=circles.length-1;i>=0;i--){
var parent=circles[i].parentNode;
if(parent)parent.removeChild(圆圈[i]);
};
//添加新的。是的,在现有的基础上更新x,y会更有意义
//圆圈,但这是为了显示在IE中添加/删除大量节点时会发生什么
对于(var j=count-1;j>=0;j--){
var节点=document.createElements(“http://www.w3.org/2000/svg“,‘圆圈’”;
node.id='id'+Math.random();
node.setAttributeNS(null,“cx”,Math.random()*800);
node.setAttributeNS(null,“cy”,Math.random()*800);
node.setAttributeNS(null,“r”,5);
setAttributeNS(null,“fill”,“blue”);
appendChild(节点);
};
}
设置间隔(更新,1000);
我发现这会慢慢泄漏IE9和IE10中的内存。有关实时版本,请参见此处:

我能做些什么(如果有的话)来防止泄漏,以及这对如何编写D3代码以IE为目标添加/删除大量节点有什么影响?

其他说明:

受此启发,我尝试了一种简单的节点池方法,将移除的节点推到堆栈上:

if (parent) circlePool.push( parent.removeChild(circles[i]) );
并在以后重新使用它们:

var node;
if (circlePool.length == 0) {
  node = document.createElementNS("http://www.w3.org/2000/svg", 'circle');
} else {
  node = circlePool.pop();
  //TODO: clear out attributes of the node
}

但这没有任何区别。

到目前为止,我发现唯一有助于IE内存使用的方法是为节点分配ID,或者为节点分配在动画迭代中重复的ID:

node.id = 'id' + j;
请参见此处的实时版本:

我认为在删除DOM节点之前清空ID也会做同样的事情,但这没有效果

我真的不喜欢这个答案,所以我希望其他人能更好地解释为什么节点池方法不起作用

但就目前而言,对于使用D3的开发人员来说,这个故事的寓意是:如果您反复添加并删除大量具有唯一ID的节点(例如从.ajax调用中获取数据库中的记录),您可能会面临内存泄漏的危险