Zenject icon indicating copy to clipboard operation
Zenject copied to clipboard

Memory leak when using BindMemoryPool with WhenInjectedInto.

Open n0uk opened this issue 4 years ago • 6 comments

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.

n0uk avatar Apr 14 '20 18:04 n0uk

Same thing happens when using BindMemoryPool with WithId.

n0uk avatar Apr 15 '20 05:04 n0uk

I will get into this. Thanks!

Mathijs-Bakker avatar Apr 29 '20 18:04 Mathijs-Bakker

@Mathijs-Bakker I fixed it by calling container.UnbindAll() from SceneContext::OnDestroy. But not sure it's a correct solution.

n0uk avatar Apr 30 '20 03:04 n0uk

But same thing happens inside GameObjectContext, so previous workaround doesn't work in this cases.

n0uk avatar May 20 '20 12:05 n0uk

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();

marshmatter avatar Sep 17 '20 17:09 marshmatter

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));

kkohno avatar Feb 10 '21 14:02 kkohno