如何删除JavaScript画布呈现上下文的状态堆栈?
我最近在用JavaScript处理如何删除JavaScript画布呈现上下文的状态堆栈?,javascript,canvas,memory-management,memory-leaks,html5-canvas,Javascript,Canvas,Memory Management,Memory Leaks,Html5 Canvas,我最近在用JavaScript处理,发现可能会造成非常严重的“内存泄漏”(更像是内存爆炸)。使用画布上下文时,您可以执行context.save()将图形样式添加到“状态堆栈”中,并执行context.restore()将其删除。(见附件。) 当您碰巧连续保存到状态堆栈而不还原时,就会出现问题。在Chrome v50和Firefox v45中,这似乎占用了越来越多的私有内存,最终导致浏览器选项卡崩溃。(顺便说一句,JavaScript内存在Chrome中不受影响,因此很难使用profiler/t
,发现可能会造成非常严重的“内存泄漏”(更像是内存爆炸)。使用画布上下文时,您可以执行context.save()
将图形样式添加到“状态堆栈”中,并执行context.restore()
将其删除。(见附件。)
当您碰巧连续保存到状态堆栈而不还原时,就会出现问题。在Chrome v50和Firefox v45中,这似乎占用了越来越多的私有内存,最终导致浏览器选项卡崩溃。(顺便说一句,JavaScript内存在Chrome中不受影响,因此很难使用profiler/timeline工具对此进行调试。)
我的问题:如何清除或删除画布上下文的状态堆栈?使用普通数组,您可以检查长度
,使用拼接
对其进行修剪,或者简单地重置为空[]
,但我还没有看到使用状态堆栈执行任何操作的方法
[一] 。。发现了造成严重“内存泄漏”的可能性
从技术上讲,这不是内存泄漏。泄漏可能是分配内存并释放指向它的指针,因此无法释放内存。在这种情况下,会跟踪指针,但不会释放内存
当您碰巧连续保存到状态堆栈而不还原时,就会出现问题
这是意料之中的。在不释放内存的情况下分配内存将累积已分配的内存块
如何清除或删除画布上下文的状态堆栈
唯一的方法是恢复所有保存的状态,或者通过为canvas元素设置一些大小(即canvas.width=canvas.width
)来重置上下文
调用restore()
的次数比调用save()
的次数要多(在这种情况下,它只返回而不执行任何操作)也很安全,因此从理论上讲,您可以通过一个n
迭代次数的循环来运行它。不过,后者更属于不良行为范畴
但话说回来:如果假设存储和恢复的数量相等,但存储和恢复的数量不匹配,则通常表示代码中的其他地方存在问题。通过重置或在post中运行多个恢复来解决问题可能只会有助于掩盖实际问题
下面是一个关于如何跟踪保存/还原调用计数的示例-
//注意:在创建画布上下文之前,需要运行此代码
CanvasRenderingContext2D.prototype.\u save=CanvasRenderingContext2D.prototype.save;
CanvasRenderingContext2D.prototype.\u restore=CanvasRenderingContext2D.prototype.restore;
//我们的补丁向量
CanvasRenderingContext2D.prototype.\uu tracker=0;
CanvasRenderingContext2D.prototype.save=函数(){
这个;
log(“Track save:,this.\u tracker”);
这个._usave()
}
CanvasRenderingContext2D.prototype.restore=函数(){
这个;
log(“跟踪还原:”,this.\u tracker);
这是.\u restore()
}
//用于转储状态的自定义方法
CanvasRenderingContext2D.prototype.trackstat=函数(){
如果(此跟踪程序)
console.warn(“跟踪状态:”,此.\u跟踪器);
其他的
日志(“跟踪状态:OK”);
}
var ctx=document.createElement(“canvas”).getContext(“2d”);
ctx.save();//执行几个save()操作
ctx.save();
ctx.restore();//单一还原()
ctx.trackstat();//应报告1的不匹配
ctx.restore();//上次还原()
ctx.trackstat();//应报告正常
[一] 。。发现了造成严重“内存泄漏”的可能性
从技术上讲,这不是内存泄漏。泄漏可能是分配内存并释放指向它的指针,因此无法释放内存。在这种情况下,会跟踪指针,但不会释放内存
当您碰巧连续保存到状态堆栈而不还原时,就会出现问题
这是意料之中的。在不释放内存的情况下分配内存将累积已分配的内存块
如何清除或删除画布上下文的状态堆栈
唯一的方法是恢复所有保存的状态,或者通过为canvas元素设置一些大小(即canvas.width=canvas.width
)来重置上下文
调用restore()
的次数比调用save()
的次数要多(在这种情况下,它只返回而不执行任何操作)也很安全,因此从理论上讲,您可以通过一个n
迭代次数的循环来运行它。不过,后者更属于不良行为范畴
但话说回来:如果假设存储和恢复的数量相等,但存储和恢复的数量不匹配,则通常表示代码中的其他地方存在问题。通过重置或在post中运行多个恢复来解决问题可能只会有助于掩盖实际问题
下面是一个关于如何跟踪保存/还原调用计数的示例-
//注意:在创建画布上下文之前,需要运行此代码
CanvasRenderingContext2D.prototype.\u save=CanvasRenderingContext2D.prototype.save;
CanvasRenderingContext2D.prototype.\u restore=CanvasRenderingContext2D.prototype.restore;
//我们的补丁向量
CanvasRenderingContext2D.prototype.\uu tracker=0;
CanvasRenderingContext2D.prototype.save=函数(){
这个;
log(“Track save:,this.\u tracker”);
这个._usave()
}
CanvasRenderingContext2D.prototype.restore=函数(){
这个;
log(“跟踪还原:”,this.\u tracker);
这是.\u restore()
}
//用于转储状态的自定义方法
CanvasRenderingContext2D.prototype.trackstat=函数(){
如果(此跟踪程序)
console.warn(“跟踪状态:”,此.\u跟踪器);
其他的
日志(“跟踪状态:OK”);
}
var ctx=document.createElement(“画布