Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/467.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何删除JavaScript画布呈现上下文的状态堆栈?_Javascript_Canvas_Memory Management_Memory Leaks_Html5 Canvas - Fatal编程技术网

如何删除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

我最近在用JavaScript处理
,发现可能会造成非常严重的“内存泄漏”(更像是内存爆炸)。使用画布上下文时,您可以执行
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(“画布