changing scenes with free() or queue_free() does not free system memory and eventually crashes

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

Greetings Go Dots.
I’m running Godot 3.1.1 and I have 32Gigs of RAM

So here’s my scenario:
I start with a basic 2D menu as the Main Scene (“res://TitleScreen.tscn”) - at this point, my mem usage is 45MB
I pick play from the menu and the script calls level01 as follows:


Level 1 of my 3D game loads up fine, now I’m up to 156MB of memory.
I press “esc” which loads an in-game menu

var pause_menu = preload(“res://PauseMenu.tscn”)
var s = pause_menu.instance()
get_tree().paused = true

I’m still at 156MB of memory usage. The menu is set to “process” during ‘pause’. I can pause and un-pause, that works fine, no changes to memory.
To UNpause I use:

get_tree().paused = false

The above dumps the part of the tree that holds the menu, again no changes to memory using this pause and un-pause.
Next I choose the menu option to get back to the main menu which runs this:


Memory usage climbs to 172MB, where in the beginning this scene only used 45MB. So I’ll choose to run Level 1 again by choosing the exact same ‘play’ option that ran it perfectly last time:


At this point the scene tries to load but none of the 3d assets appear this time. I can’t bring up my menu, and it shows me an empty 3D viewport.

I am stumped. Help?

When you execute the self.queuefree(), what exactly is it that is destroyed? Where does this bit of code run from?

johnygames | 2019-08-06 05:21

the queuefree() is there to destroy the in-game menu. Layout there looks like this:

  • Spacial Level 01
    -Spacial for Player {scene instance} (blender import)
    -Node2d Pause Menu Loader {scene instance} <<<-- menu point

At the “menu point” I’m adding in a scene with

var s = pausemenu.instance()
gettree().paused = true

That adds on a node2D scene instance with more labels for menu options and from the top level of that node2D scene instance, I’m navigating up to the same menu point (with get_parent() ) using queue_free() at the same menu point where the menu was added.

Brinux | 2019-08-06 12:37

Good question. I was going to say you should open an issue on Github but it was just a misunderstanding haha.

adonispujols | 2019-08-06 18:29

:bust_in_silhouette: Reply From: BraindeadBZH

Quote from the documentation of queue_free():

This method ensures it’s safe to delete the node

I’m pretty sure that means that if you don’t call remove_child() prior to deletion then the node cannot be freed.

:bust_in_silhouette: Reply From: Zylann

If you want to remove a node immediately from the tree instead of queue_free(), you could do something like this:


Queue_free() is actually working as expected.

My issue is that when I use get_tree().change_scene("res://TitleScreen.tscn") it appears that the current scene (that I want to leave behind) never dies.

I’m considering re-structuring the whole project to use scene.instance() w/ add_child() adds and queue_free() for subtracts and abandoning change_scene("different scene") usage entirely.

Change_scene seems to work great in small-scale testing, but when I start hanging scripts and imported scenes everywhere, pretty soon it stops releasing the memory of the old scene.
It’s very possible (and likely) I’m the cause of the problem, but I’m trying to keep this simple to troubleshoot and there’s just not much going on in my project yet.

Brinux | 2019-08-06 13:05

Hi, sorry the late response, but did your approach made it better? (Because i’m facing similuar issues, though freeing scenes - somehow they seem to cause memory leaks when i change like >4 scenes. Thinking about restructering the project to your proposed logic.)

Captain.Susuwatari | 2020-02-03 09:04