Zenject
Zenject copied to clipboard
Memory leak when using BindMemoryPool with WhenInjectedInto.
When using BindMemoryPool and WhenInjectedInto - scene context doesn't unloaded after destroying scene.
Project to reproduce: https://github.com/n0uk/ZenjectMemoryLeak
Open scene0 and run it, and output will be: Instance count: 1 Instance count: 0 ... Instance count: 1 Instance count: 0
There should be zero instances.
Everything is fine, but set the checkbox in Installers/TestClassUsingPoolsInstaller - "Install with When Loaded Injected Into":
if (InstallWithWhenInjectedInto)
{
binding.WhenInjectedInto<TestClassUsingPools>();
}
Run scene0 again, and you can see output like:
Instance count: 1 Instance count: 2 Instance count: 3 ... Instance count: 10 There should be zero instances.
So SceneContext duplicated in memory 10 times for now.
Same thing happens when using BindMemoryPool with WithId.
I will get into this. Thanks!
@Mathijs-Bakker I fixed it by calling container.UnbindAll() from SceneContext::OnDestroy. But not sure it's a correct solution.
But same thing happens inside GameObjectContext, so previous workaround doesn't work in this cases.
Looks like I'm hitting this same thing with WithId rather than WhenInjectedInto. Injection is into both SceneContext and GameObjectContext.
e.g.
Container.BindMemoryPool<ExplosionHandler, ExplosionHandler.Pool>()
.WithId("VehicleCollision")
.WithInitialSize(20)
.ExpandByOneAtATime()
.FromComponentInNewPrefab(vehiclePhysicsConfig.collisionExplosion)
.UnderTransformGroup("(Pool) Vehicle Collision Effects")
.MoveIntoAllSubContainers();
same problem - i am installs pools on GameObjectContext, then my system reloads the scene and Pool Monitor has two pools etc... pools are cause of memory leaks.
GameObjectContext installer code (every pool causes the leaks):
Container.BindFactory<string, PreassetSourceLineAdapter, PreassetSourceLineAdapter.Factory>()
.FromMonoPoolableMemoryPool(p =>
p.FromComponentInNewPrefab(m_PreassetSourceLinePrefab).UnderTransform(m_LinesContent));
Container.BindFactory<string, PreassetSourceDirectoryLineAdapter, PreassetSourceDirectoryLineAdapter.Factory>()
.FromMonoPoolableMemoryPool(p => p.FromComponentInNewPrefab(m_PreassetSourceDirectoryLinePrefab).UnderTransform(m_LinesContent));