使用 p5.js 通过 createGraphics() 生成的对象未被垃圾收集
Objects generated with createGraphics() using p5.js are not being garbage-collected
我正在绘制一个简单的草图,我想在其中为用户提供撤消功能。为此,我决定跟踪用户在使用 createGraphics() 创建的对象中所做的每一笔画(画一条线,改变颜色,...) 反过来,它在像堆栈 (LIFO) 一样处理的数组中进行管理。经过一些测试后,我注意到浏览器使用的内存量从未减少,并在 p5.js repo 中读到该问题必须通过使用 remove() ,我没有用。
因为我找不到很多关于它的信息,我假设 remove() 方法可以正常工作问题出在我的实施中。这是复制问题的非常详细的骨骼草图:
function setup(){
c = createCanvas(windowWidth, windowHeight);
mouseClicked = mo;
}
function mo(){
let ppp = createGraphics(5000, 5000); // oversized to make the memory usage obvious
ppp.background(color(random(255), random(255), random(255)));
image(ppp, 0, 0);
ppp.remove();
ppp = null;
}
前面的代码片段每次点击都会使用大约 100MB 的内存,但有趣的是,只有在第三次点击后才开始这样做。
我怎么做错了?如何成功删除使用 createGraphics() 创建的对象并释放它使用的内存?
显然问题出在 p5 库中,特别是在 p5.Graphics.js 中。还好,不错people at github came through with a solution。现在,可以通过重写删除函数来解决问题:
p5.Graphics.prototype.remove = function() {
if (this.elt.parentNode) {
this.elt.parentNode.removeChild(this.elt);
}
var idx = this._pInst._elements.indexOf(this);
console.log(this._pInst);
if (idx !== -1) {
this._pInst._elements.splice(idx, 1);
}
for (var elt_ev in this._events) {
this.elt.removeEventListener(elt_ev, this._events[elt_ev]);
}
};
我正在绘制一个简单的草图,我想在其中为用户提供撤消功能。为此,我决定跟踪用户在使用 createGraphics() 创建的对象中所做的每一笔画(画一条线,改变颜色,...) 反过来,它在像堆栈 (LIFO) 一样处理的数组中进行管理。经过一些测试后,我注意到浏览器使用的内存量从未减少,并在 p5.js repo 中读到该问题必须通过使用 remove() ,我没有用。
因为我找不到很多关于它的信息,我假设 remove() 方法可以正常工作问题出在我的实施中。这是复制问题的非常详细的骨骼草图:
function setup(){
c = createCanvas(windowWidth, windowHeight);
mouseClicked = mo;
}
function mo(){
let ppp = createGraphics(5000, 5000); // oversized to make the memory usage obvious
ppp.background(color(random(255), random(255), random(255)));
image(ppp, 0, 0);
ppp.remove();
ppp = null;
}
前面的代码片段每次点击都会使用大约 100MB 的内存,但有趣的是,只有在第三次点击后才开始这样做。
我怎么做错了?如何成功删除使用 createGraphics() 创建的对象并释放它使用的内存?
显然问题出在 p5 库中,特别是在 p5.Graphics.js 中。还好,不错people at github came through with a solution。现在,可以通过重写删除函数来解决问题:
p5.Graphics.prototype.remove = function() {
if (this.elt.parentNode) {
this.elt.parentNode.removeChild(this.elt);
}
var idx = this._pInst._elements.indexOf(this);
console.log(this._pInst);
if (idx !== -1) {
this._pInst._elements.splice(idx, 1);
}
for (var elt_ev in this._events) {
this.elt.removeEventListener(elt_ev, this._events[elt_ev]);
}
};