I’m not entirely sure on how references to objects can cause memory leaks. Does any of these code below have memory leaks. If not what causes memory leaks on references and why?
Example 1
local Part = workspace.Part
local function PrintName()
print(Part.Name)
end
PrintName()
Example 2
local function PrintName()
local Part = workspace.Part
if Part.Name == "Part" then
local OtherPart = workspace.OtherPart
print(OtherPart.Name)
end
print(Part.Name)
end
PrintName()
Example 3
local function PrintName()
local Part = workspace.Part
if Part.Name == "Part" then
do
local OtherPart = workspace.OtherPart
print(OtherPart.Name)
end
end
print(Part.Name)
end
PrintName()
Because PrintName internally references Part, if Part is destroyed it will never truly get garbage collected because there is always a hanging reference to Part through PrintName.
You could expect there to be a memoryleak? I’m not entirely sure because I never dabbled in attempting to figure out how Lua garbage collection actually works.
Both the second and third example set the reference within the function, so they shouldn’t leak. It’s creating a new reference every time that the function runs. The first one might, because it still holds a reference to Part that is used.
If you drop the Part variable it becomes nil in the function as wel.
local Part = workspace.Part
local function PrintName()
print(Part.Name)
end
Part = nil
PrintName() --// attempt to index a nil value with '.Name' or something
Just set Part to nil at some point. You can check for its AncestryChanged event to see when it gets removed from the workspace, and set the variable to nil then.
Might not be relevant to the question, but its good to know;
When you reference tables and objects and store them in variables, the table / object cannot be garbage collected because there is something somewhere pointing to it. The object / table will not be completely cleaned up until nothing is referring to it.
When you set a variable to a table, it doesn’t copy the table:
local a = {"a", "b", "c"} -- create table a
local b = a -- b references a
a[1] = "d"
print(b[1]) -- prints "d" because b references the table and doesnt copy it
However, if you were to do the same with an integer, it copies:
local a = 4 -- Integer
local b = a -- Copies the value of a at this time
a = 5 -- Changing a does not change b
print(b) -- prints 4 because it simply copied a
In a case where say I use a spawn/coroutine inside the same function “PrintName” and reference another part within the new spawn/coroutine function, does it create the reference in a new scope and gets garbage collected as well?
I’m not sure this is a good example. You’re completely overwriting the variable here. It’s not like the variable is tied to the string. And strings are indeed passed by reference, and are immutable. So it’s hard to show reference this way.
When you reference tables and objects and store them in variables, the table / object cannot be garbage collected because there is something somewhere pointing to it. The object / table will not be completely cleaned up until nothing is referring to it.
Even if that table has strong references, it will be garbage collected since that “strong reference” is cleared assuming its allocated on the stack. If on the heap, you would have to remove that strong reference manually.
do
local a = {"a", "b", "c"}
local b = a -- a now has a strong reference to its value, b
end
-- the (do) stack ends, a and b are now nil (both of them are removed from memory)
-- when the stack ends, b is garbage collected since it has no strong references.
-- when b is nil, a has no strong references and is garbage collected as well