-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Memory leak when using weakref()
#90086
Comments
I'm guessing this is how it's supposed to work, as it's not supposed to un-allocate the memory. It also says this in the documentation, that until the game needs the memory, it won't delete the objects. |
"Objects" in "Monitors" panel shows the number of objects growing indefinitely. Changing Assigning the weak reference to a plain var x: MyObj = weakref(obj_2)
# ERROR: Trying to assign value of type 'WeakRef' to a variable of type ''. I guess something wrong happened during the implicit conversion. |
Use class MyObj:
var id: int
var obj: MyObj
func _init(p_id: int) -> void:
id = p_id
func _notification(what: int) -> void:
if what == NOTIFICATION_PREDELETE:
prints(id, "freed")
func _run() -> void:
var obj_1 = MyObj.new(1)
var obj_2 = MyObj.new(2)
#obj_1.obj = obj_2 # Does not leak.
obj_1.obj = weakref(obj_2) # Does not leak. class MyObj:
var id: int
var obj: WeakRef # <-- !!!
func _init(p_id: int) -> void:
id = p_id
func _notification(what: int) -> void:
if what == NOTIFICATION_PREDELETE:
prints(id, "freed")
func _run() -> void:
var obj_1 = MyObj.new(1)
var obj_2 = MyObj.new(2)
obj_1.obj = obj_2 # `obj_2` leaks.
#obj_1.obj = weakref(obj_2) # Does not leak.
The implicit conversion between |
There's no casting at least not valid casting occurring, try just The leak in the Edit: It happens regardless of what's contained in obj_1.obj = obj_2
obj_1.obj = weakref(obj_2) And it still happens Edit 2: var w : WeakRef = obj_2 Fails with an error at runtime, so something is wrong with how |
Will try dig into the casting or conversion of refcounted, seems to be some glitch with the count increment: print(obj_2.get_reference_count()) # Prints 1
obj_1.obj = obj_2
print(obj_2.get_reference_count()) # Prints 2! |
If the base type is not known at compile time, then the property is assigned as follows:
And
|
The code that's causing the leak is this: godot/modules/gdscript/gdscript.cpp Lines 1605 to 1612 in 29b3d9e
Something about how it handles conversions here means the value leaks, even though at the end of the conversion Can't quite find what in the code is broken exactly, probably something in: godot/core/variant/variant_construct.cpp Lines 331 to 348 in 29b3d9e
Not handling something correctly |
It seems that it's due to how the construction of an object doesn't correctly assign type, so it's a Will write up a fix, new changes makes it error on runtime, and doesn't leak |
Tested versions
System information
Godot v4.2.1.stable - Windows 10.0.19045 - Vulkan (Mobile) - dedicated NVIDIA GeForce GTX 980 Ti (NVIDIA; 31.0.15.3699) - Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz (8 Threads)
Issue description
The following code leaks memory:
If you swap the commented line with the line that leaks, it will no longer leak.
This also happens with other types:
I expect that
weakref()
should not have this sort of impact in this scenario. Please correct me if I am mistaken!With
weakref()
:Without
weakref()
:Steps to reproduce
Minimal reproduction project (MRP)
weakref-leak-bug.zip
The text was updated successfully, but these errors were encountered: