[Solved] Unable to manage some leaked instance on exit...

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By sante

Hi everyone.

My game needs to load certain types of characters quickly and, as you know, loading them from disk every time can be a problem, at least in terms of performance.
But Godot has his own solutions called “Resource” (the class I mean). So if I have a reference to a Resource object and ask to load it again from disk, under the hood Godot just makes a copy of that into memory, making the process much faster.

Okay. Let’s think about how to exploit this behavior… I created a Dictionary where the keys are the path to the scenes and the values ​​are the Resource object referring to those scenes.
When the game starts, I load all these resources I need with the ResourceLoader by storing the references in that dictionary. It works very well! I can instantiate hundreds of items without any kind of FPS loss… Great!

When I close the game, unfortunately I get a lot of “Leaked Instance” and “Resource still in use” error messages in the log. I’m sure the problem comes from that dictionary because if I disable the lines of code that create it, these errors go away.

It seems that the resources I load aren’t freed properly before closing the game, but the resource manual says this process is automatic. Also consider that, before closing the game, I delete the references to the loaded resources from the dictionary simply using its clear() method…

In your opinion, where is the problem?

:bust_in_silhouette: Reply From: zhyrin

I would assume cyclic references. Some things you load reference each other. Since each are referenced by something else, they can’t be unloaded.

Why is it beneficial for you to store loaded scenes in a dictionary? The point of the load optimization is that you don’t have to manually keep a reference, godot will know if the resource is currently loaded.

You could try a) storing weak references in your dictionary b) before shutdown manually nulling the dctionary (possibly all the values too). But I’m unsure if this would fix your memory leak.

First of all, thanks for the reply.

The problem is related to a whole series of elements, such as enemies, explosions, bullets, etc.

I invented this dictionary technique when I could see that, during the game, there were moments of “block” due to loading these characters from disk. Obviously it only happened on the first load, but it was still very annoying, due to the very fast game.

The absurd thing is that loaded in the dictionary or elsewhere, they are always loaded in the same way… Yet, by disabling the loading in the dictionary, I have the problem of black-outs when loading from disk, while using the dictionary, the loading is fast but I get the missing references when closing the application.

sante | 2023-03-12 10:39

If you run godot from a command line, you can supply the --verbose argument, this will give better output to see where the leak happens. I used it in a multithreaded project, the output has some “duplication” if I remember correctly.

Have you tried using preload() instead of load()? That might help with the load stutter.

zhyrin | 2023-03-12 11:26

Solved! But I didn’t understand much. There was simply an object derived directly from Object class that was not, correctly, freed. I simply put it at null, when it need to be deleted by its free() method.
It’s strange, however, that the errors only came up when loading classes in the dictionary, since that object is used globally… It’s kind of a mystery…
I know only now works…

sante | 2023-03-12 16:28