LayaAir
LayaAir copied to clipboard
销毁节点后存在资源内存泄露
节点销毁后其组件可能过一会才会销毁,导致依赖的资源引用计数过一会儿才会-1, 所以释放完资源以后立即调用destroyUnusedResources
并不会生效,从而导致的内存泄露。
通过这段代码的调用堆栈可以看到,组件的 onDestroy 调用顺序不一致。
class TestCompoenent extends Laya.Component {
onDestroy(): void {
console.trace('onDestroy', this.constructor.name, this.owner.name);
}
}
const parent = new Laya.Sprite3D();
parent.name = 'parent';
parent.addComponentInstance(new TestCompoenent());
const child = new Laya.Sprite3D();
child.name = 'child';
child.addComponentInstance(new TestCompoenent());
parent.addChild(child);
scene.addChild(parent);
查看堆栈
onDestroy TestCompoenent parent
onDestroy @ Scene_SampleScene.ts:18
_destroy @ Component.ts:244
callDestroy @ ComponentDriver.ts:105
destroy @ Scene3D.ts:1426
dispose @ LayaScene.ts:77
unload @ LayaScene.ts:49
(anonymous) @ 3DContainerPage.ts:41
(anonymous) @ RecordPage.ts:80
__async @ RecordPage.ts:80
(anonymous) @ 3DContainerPage.ts:40
invoke @ Delegate.ts:94
event @ EventDispatcher.ts:40
bubbleEvent @ InputManager.ts:589
handleMouse @ InputManager.ts:254
canvas.addEventListener.passive @ InputManager.ts:118
onDestroy TestCompoenent child
onDestroy @ Scene_SampleScene.ts:18
_destroy @ Component.ts:244
callDestroy @ ComponentDriver.ts:105
_runComponents @ Stage.ts:916
render @ Stage.ts:842
_loop @ Stage.ts:749
loop @ Render.ts:104
requestAnimationFrame (async)
loop @ Render.ts:112
requestAnimationFrame (async)
loop @ Render.ts:112
深入看了一下代码是删除节点时重置 parent 属性时将 _scene 属性设为了 null 导致节点无法正确定位其所属的场景的ComponentDriver ,选用 stage 提供的备选方案, 此方案并非同步操作。