如何删除JavaScript画布呈现上下文的状态堆栈
How to delete the state stack for a JavaScript canvas rendering context?
我最近在JavaScript中使用<canvas>
,发现了造成严重"内存泄漏"(更像内存爆炸)的可能性。使用画布上下文时,可以使用context.save()
将绘图样式添加到"状态堆栈",使用context.restore()
将其删除。(有关MDN上的渲染上下文,请参阅文档。)
当您碰巧连续保存到状态堆栈而不进行恢复时,就会出现问题。在Chrome v50和Firefox v45中,这似乎只占用了越来越多的私人内存,最终导致浏览器选项卡崩溃
我的问题是:如何清除或删除画布上下文的状态堆栈使用普通数组,您可以检查length
,用splice
修剪它,或者简单地将其重置回空的[]
,但我还没有看到用状态堆栈执行这些操作的方法。
[I] 。。发现了创建一个非常糟糕的"内存泄漏"的可能性
从技术上讲,这不是内存泄漏。泄漏是指分配内存并释放指向内存的指针,使其无法释放。在这种情况下,会跟踪指针,但不会释放内存。
当您碰巧连续保存到状态堆栈而不进行恢复时,就会出现问题。
这是意料之中的事。在不释放内存的情况下分配内存将累积已分配的内存块。
如何清除或删除画布上下文的状态堆栈?
唯一的方法是恢复所有保存的状态,或者通过为画布元素设置一些大小来重置上下文(即canvas.width = canvas.width
)。
调用restore()
的次数比调用save()
的次数多也是安全的(在这种情况下,它只是返回而不做任何事情),因此理论上可以通过n
迭代次数的循环来运行它。不过,后者更属于不良行为类别。
但话虽如此:如果在假定相等的情况下,保存和恢复的数量不匹配,通常表明代码中的其他地方存在问题。通过重置或在事后运行多个恢复来解决问题可能只会掩盖实际问题。
下面是一个关于如何跟踪保存/恢复调用计数的示例-
// NOTE: this code needs to run before a canvas context is created
CanvasRenderingContext2D.prototype.__save = CanvasRenderingContext2D.prototype.save;
CanvasRenderingContext2D.prototype.__restore = CanvasRenderingContext2D.prototype.restore;
// Our patch vectors
CanvasRenderingContext2D.prototype.__tracker = 0;
CanvasRenderingContext2D.prototype.save = function() {
this.__tracker++;
console.log("Track save:", this.__tracker);
this.__save()
}
CanvasRenderingContext2D.prototype.restore = function() {
this.__tracker--;
console.log("Track restore:", this.__tracker);
this.__restore()
}
// custom method to dump status
CanvasRenderingContext2D.prototype.trackstat = function() {
if (this.__tracker)
console.warn("Track stat:", this.__tracker);
else
console.log("Track stat: OK");
}
var ctx = document.createElement("canvas").getContext("2d");
ctx.save(); // do a couple of save()s
ctx.save();
ctx.restore(); // single restore()
ctx.trackstat(); // should report mismatch of 1
ctx.restore(); // last restore()
ctx.trackstat(); // should report OK
- 将函数的上下文应用于javascript变量
- Twitter Bootstrap typeahead:使用“this”获取上下文/调用元素
- ReactJS映射:如何仅在url变量不为空时呈现html链接
- 循环结束/推送到数组之前在页面上呈现EJS
- 使用JQuery的动态上下文菜单
- 如何从资产Javascript中呈现分部
- 表达式引擎扩展开发-向呈现的条目添加自定义javascript
- 以块形式呈现大型HTML表
- 如何访问UIWebView'的子窗口上下文
- 主干窗体隐藏字段未呈现
- 为什么不't我的变量在我的控制器中填充后在我的视图中呈现
- 如何删除JavaScript画布呈现上下文的状态堆栈
- 画布的奇怪行为 上下文变量定义位置导致选项卡处于非活动状态时画布呈现冻结
- Handlebars未呈现JSON上下文数据,正在获取空模板
- 未指定必需的上下文“router”.检查“RoutingContext”的呈现方法
- 当前上下文值不会从Usercontrol呈现到.aspx页面
- 呈现子组件时无法设置上下文
- 在呈现的回调中访问数据上下文
- Reactjs:在带有上下文的客户端上呈现原始html
- 如何在 JavaScript 中呈现两个时间戳之间的上下文差异