+6 votes

What is the best way to free resources. I know you can call '.free' on a node/ some resource but how to check if a resource is locked or being used and delay freeing if so.

in Engine by (254 points)

4 Answers

+5 votes
Best answer

You can use .queue_free() on a node to free it after it has finished any processing and has reached an "idle" state.

by (76 points)
selected by
+5 votes

Use queue_free(), so the object finishes it's own processing. But you also need to work the other way around—objects referencing other objects should check that the object still exists before trying to do things with it. If you get crashes, try checking if the object != null, or if object.is_inside_tree() before using it.

I've also had issues with collisions and different scripts running on process and fixed process. Apparently objects queue freed during process can still register a collision in the next fixed process, but by that time the object is already gone, so any attempt to, say, get_contact_collider_object() will cause a crash. Not sure how that's possible, but fortunately it was easy enough to fix by running both scripts on fixed_process.

by (532 points)
edited by
+8 votes

To complement rgrams answer, if the object is going to be freed, you may want to keep a "weak" reference on it if the node is going to be referenced in other parts of the code:

    var node_ref =  weakref(node_to_be_freed_somtime)

    if node_ref.get_ref() != null:
         node_ref.get_ref().use_object()
    else:
         print("Node has been deleted")

thats is a correct way to maintain a safe and checkeable reference to object that are going to be deleted.

Cheers.

by (44 points)

Ah, I saw that the other day but haven't gotten around to trying it yet. Good to know it works as hoped.

Saved my life!! Thx a lot.

So should I understand the concept like this:
If an object/node is intended to be used and freed again and again, we should keep a weak reference for later check.

that's just what I was looking for!
I used that trick on Godot 3.1 to get rid of HTTPRequest node just before switching to new scene.

thanks a lot!

+1 vote

[   reference for : " What is the best way to free resources. "   ]

  =====================================================
    Code and quotes are from :
    [ Docs » Step by step » Scripting (continued) -- creating nodes ]
  =====================================================

 
node.free() can lead to crashes :

func _someaction():
    s.free() # immediately removes the node from the scene and frees it

 
Dangers of using node.free() :

"However, it might happen very often that we want to delete a node that is currently “blocked”, because it is emitting a signal or calling a function. This will result in crashing the game."

 

node.queue_free()
queues the node to be freed as soon as it can safely be removed

func _someaction():
    s.queue_free() # remove the node and delete it 
                   #  while nothing is happening

"The safest way to delete a node is by using Node.queue_free(). This erases the node safely during idle."

by (116 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.