layabox / LayaAir

LayaAir is a fully platform rendering engine with rich 2D/3D rendering capabilities and a mature integrated development platform

Home Page:https://www.layaair.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

销毁节点后存在资源内存泄露

Geequlim opened this issue · comments

节点销毁后其组件可能过一会才会销毁,导致依赖的资源引用计数过一会儿才会-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 提供的备选方案, 此方案并非同步操作。