I'm working on hunting down a few memory leaks in my project, and one thing that surprises me is that it doesn't seem like queue_free()
nor free()
are called on objects when they're effectively removed from the game by doing a get_tree().change_scene("path")
call.
If I override queue_free()
or free()
to just print the fact that they're called this won't happen upon scene changing nor SceneTree.quit()
. Yet _exit_tree()
does get called for such objects. While I'm currently overriding that for my destructor hooks it's not ideal -- it means any such objects can never be removed from and then re-added to the tree.
Does anyone know how objects are destroyed when Godot changes scenes or quits the application, and which function calls I can override during this process?
Of lesser importance, why aren't either free()
or queue_free()
called in a way that can be overridden during quit()
or change_scene()
?
Edit: It's worth noting that it does not look like free()
can be overridden the same way as other functions can. Be warned if trying to do so for debugging purposes.
Edit 2: Also, unlike _ready()
, queue_free()
does not chain down the tree of objects. It's only called on the object it's called on, though presumably that object's children are free()
d.
If you want to implement destructor-style logic, do it on NOTIFICATION_PREDELETE.
That notification will be received by anything which can exist in memory, be it an Object
(which must be manually free()
d), Node
-based (which can either be freed up directly or will automatically be freed if their parent gets freed, but will not be automatically freed if they're not part of the scene tree in some capacity), or Reference
-based objects (which untyped classes default to) right before they're automatically freed when no longer referenced.