#[BUG] Leaks in 1.3.2

1 messages · Page 1 of 1 (latest)

rose sky
#

Getting 6-8 leaks since updating to 1.3.2 from within subscene streaming, all have similar but slightly different stacks

#

Except this one, which is quite different as it's happening in CreateEntity?

#

Unity 6000.0.20

#

[BUG] Leaks in 1.3.2

olive mist
#

Out of curiousity, are these leaks reported after a serialization/streaming operation fails? The last time I reviewed memory leaks in the Entities package, we discovered that DeserializeWorld is particularly bad at cleaning up after itself in the event of an error. So to some degree I'd expect something like that (even if I don't love it). But if this is happening during/after a successful load, that's far more concerning.

rose sky
#

i'm not really getting any other errors

#

also this project is pretty empty tbh, i only has 1 entity in a subscene with some config data - i was mostly just writing a menu to work with an ecs project

#

someone else seems to have report this on the forums and they think it's related to having netcode in project (which I do have in this specific project as well)

olive mist
#

Thanks -- I'm looking through the deserialization dispose code right now, and have yet to find something that has changed more recently than ~2021. Are these leak reports new in 1.3.2?

rose sky
#

i didn't have them before 1.3.2, i did update unity at same time as 1.3.2

#

though this was also a reasonably new project only a couple of days before i updated to 1.3.2 so maybe i just missed them

#

i hadnt used netcode for about 6 months before this

olive mist
#

The callstack truncation is just because whatever buffer size somebody arbitrarily chose for these error messages is consistently smaller than the average Unity callstack, which is a terrible idea if you want to see where you leak is actually coming from. I'll lobby to get that limit increased.

rose sky
#

oh please do, i've run into issues because of that before

olive mist
#

the netcode presence does sound like it would explain the CreateEntity() leak, if it's disabling the code that would clean up the EntityStore. The remaining leaks seem unrelated though.

#

actually the one that goes through Unity.Collections.LowLevel.Unsafe.UnsafeList`1<Unity.Entities.Serialization.SerializeUtility/MegaChunkInfo>:SetCapacity could be the same issue

rose sky
#

what drives me a little crazy about this is i don't have a reliable repro and it just seems random

#

i feel like it should be consistent...

rose sky
#

yeah tried to repro it for like 30min before, no luck

#

start doing some coding, got my 8 leaks within 5min -_-

olive mist
#

Dang, I was about to ask if you could pass along a repro project; there's a lot of paths through the subscene streaming code, and one side effect of the truncated stack traces is I can't necessarily see which one you're using

rose sky
#

did you still need a repro? I think I finally found one for at least something

#

at least 4 of the leaks, i can reliably trigger these ones

#

@olive mist , if you need my repro is as follows

        private static async void Repro()
        {
            for (var i = 0; i < 10; i++)
            {
                BovineLabsBootstrap.Instance.CreateGameWorld();
                await Task.Delay(1); // tick a frame to let world update once then dispose
                await Task.Delay(1);
                BovineLabsBootstrap.Instance.DestroyGameWorld();
                await Task.Delay(1);
                await Task.Delay(1);
            }

            BovineLabsBootstrap.Instance.CreateGameWorld();
        }```

produces 9 leaks after hitting my reload domain button
#

where create/destroy is just the basic setup for a game world

        public void CreateGameWorld()
        {
#if !UNITY_SERVER
            if (this.gameWorld != null)
            {
                throw new Exception("GameWorld has not been correctly cleaned up");
            }

            this.gameWorld = new World("GameWorld", WorldFlags.Game);
            World.DefaultGameObjectInjectionWorld = this.gameWorld; // replace default injection world


            var systems = DefaultWorldInitialization.GetAllSystemTypeIndices(WorldSystemFilterFlags.Default);
            DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(this.gameWorld, systems);
            ScriptBehaviourUpdateOrder.AppendWorldToCurrentPlayerLoop(this.gameWorld);
#endif
        }

        public void DestroyGameWorld()
        {
#if !UNITY_SERVER
            World.DefaultGameObjectInjectionWorld = ServiceWorld;

            if (this.gameWorld is not { IsCreated: true })
            {
                return;
            }


            this.gameWorld = null;
#endif
        }```
#

i'm streaming in a single subscene after loading the world using SceneSystem.LoadSceneAsync in OnStartRunning

#

i can probably package this up in a standalone project or just send the existing project if required

olive mist
#

Thanks, tomorrow I'll try just pasting your code to start; if that doesn't work we'll try a full project.

olive mist
#

...yeah there's enough outside dependencies here, a standalone project would be easier if that's not too much trouble.

rose sky
#

Will try find some time today to see if I can get it in a small repro otherwise I'll put the whole thing up

rose sky
#

@olive mist ok got a super simple tiny repro

#
  • load the sample scene
  • enter play mode
  • leave play mode
  • click repro/domainreload
#

should get 36 leaks

#

2 scripts, bootstrap just destroys and creates world over and over

    public class Bootstrap : ICustomBootstrap
    {
        public bool Initialize(string defaultWorldName)
        {
            CreateWorld();

            Repro();

            return true;
        }

        private async void Repro()
        {
            for (var i = 0; i < 10; i++)
            {
                await Task.Delay(1);
                await Task.Delay(1);
                World.DefaultGameObjectInjectionWorld.Dispose();
                await Task.Delay(1);
                await Task.Delay(1);

                CreateWorld();
            }
        }

        private void CreateWorld()
        {
            var world = new World("World", WorldFlags.Game);

            World.DefaultGameObjectInjectionWorld = world;

            var systems = DefaultWorldInitialization.GetAllSystemTypeIndices(WorldSystemFilterFlags.Default);
            DefaultWorldInitialization.AddSystemsToRootLevelSystemGroups(world, systems);
            ScriptBehaviourUpdateOrder.AppendWorldToCurrentPlayerLoop(world);
        }

        [MenuItem("Repro/DomainReload")]
        private static void DomainReload()
        {
            EditorUtility.RequestScriptReload();
        }
    }```
#

and system just loads the subscene

public partial class LoadSubsceneSystem : SystemBase
{
    protected override void OnStartRunning()
    {
        var loadingParams = default(SceneSystem.LoadParameters);
        loadingParams.AutoLoad = true;

        SceneSystem.LoadSceneAsync(this.World.Unmanaged, Object.FindAnyObjectByType<SubScene>().SceneGUID, loadingParams);
    }

    protected override void OnUpdate()
    {
    }
}```
#

(the subscene is marked as not auto loaded)

#

that's it

#

5/5 repro for me

olive mist
#

repro'd. Thanks!

olive mist
#

(for any other Unity folks who find this thread, this leak is tracked as DOTS-10668)

rose sky
#

started seeing leaks in transport package now via netcode now...