Hi, first post on the forum, so excuse me if this is a bit convoluted.
I’m working on a larger game project at the moment, and I figured it might be smart to make a controlled garbage collection script/module I can call up any time I need it.
It works by simply having all my variables inside a table inside code that I know is will be temporary. Then I can just pass those variables to the module and it does all the work without much issue. This works, I think? It causes a single frame freeze pictured below, but I think it does what it’s supposed to.
What I’m wondering about is if this is necessary? The use case I have currently is for a UI that gives weapons to the player upon spawning in. This is a UI that is given to you upon spawning in from StarterGUI, and wont be needed afterwards – which is why I deem it temporary.
Is there also a better method to doing this? Because the client freeze feels like a sign that I’m doing something wrong. That’s all. Any feedback is appreciated. Thanks.
LocalScript where it's called
maid = require(game:GetService("ReplicatedStorage").maid)
event = game:GetService("ReplicatedStorage").Events.GiveWeapon
Variables = {
mainUI = script.Parent,
pressed = false,
button = ""
}
local func
local function Presser(button)
func:Disconnect()
func = nil
print(button)
event:FireServer(button.Text)
maid.CleanAll(Variables)
event = nil
maid = nil
button = nil
end
for i,name in pairs(Variables.mainUI.List:GetChildren()) do
if name:IsA("TextButton") == true then
if name.Name ~= "Template" then
Variables.button = name
func = Variables.button.Activated:Connect(function()
Presser(Variables.button)
end)
end
end
end
Module Code
local rus = game:GetService("RunService")
local maid = {}
function maid.CleanAll(Variables) -- fully cleans given table
for num, item in pairs(Variables) do
if type(item) == ("userdata") then -- if it's an instance
if item.Parent == game then -- if it's a service
item = nil
else -- if it's anything else but a service
item:Destroy()
item = nil
end
else -- if it's a non-instance object
item = nil
end
end
Variables = nil
end
function maid.VariableClean(Variables) -- cleans variables from table
for num, item in pairs(Variables) do
task.wait()
if type(item) ~= ("userdata") then -- if it isn't an instance
item = nil
else
end
end
Variables = nil
end
function maid.InstanceClean(Variables) -- cleans instances from table
for num, item in pairs(Variables) do
task.wait()
if type(item) == ("userdata") then -- if it's an instance
if item.Parent ~= game then -- if it's a instance
item:Destroy()
item = nil
end
end
end
Variables = nil
end
return maid
Variables are collected automatically in Roblox, so you don’t need it, it will just possibly cause leaks instead of helping
What i’ve did a year ago is making Cleaning module that isn’t periodical clear, rather just insta-destroyer of custom objects, i’ve only included rblx objects such as:
Threads
Instances
Connections
Metatables
Setting table keys to nil + recursion
If i want to destroy custom objects like table that’s OOP object, or DOD table, i just create Destroyer method that i’ll call every time, it’s working as i didn’t encountered serious memory leaks in a while
EDIT: You really don’t have to care about memory leaks before you make your game, then you can rewrite it or fix it, if you have a game, and it’s popular - you know it’s worth making it actually good and optimized
Your code isn’t doing what you think it’s doing. In the for loop of your VariableClean function, doing item = nil sets the item variable to nil, but it does not modify the contents of Variables in any way. The same thing goes for the Variables parameter; doing Variables = nil does not actually modify the table that Variables is referencing – it just tells the script that you want the Variables parameter to stop referencing the table. You need to set the keys of the table to nil directly:
function maid.VariableClean(Variables)
for num in pairs(Variables) do -- don't need the item variable
Variables[num] = nil -- remove the table key directly
end
-- no point in doing Variables = nil
end
When the function ends, the Variables parameter ceases to exist thus removing its reference to the table you passed in. Edit: Even if you do Variables = nil in the module script, the Variables reference in the local script still doesn’t get cleaned when you do maid.CleanAll(Variables) (the Variables parameter in the module script is nil but the Variables in the local script is still referencing the same table thus leaking memory anyway). If you’re using a language with pointers like C then you can achieve something like this, but Lua doesn’t give you precise control over memory addresses. You still have to set the Variables in the local script to nil every time you call maid.CleanAll:
-- local script
maid.CleanAll(Variables)
Variables = nil
I wouldn’t recommend doing this anyway. Having to keep all your variables in a table adds extra overhead plus it isn’t necessary for good memory management. There are open-source maid modules that you can use if you want, but I manage 17,000 lines of code just fine without a maid. My servers run up to 24 hours at a time and don’t experience any growth in memory. You just have to watch out for upvalues in event callbacks.
I didn’t realize this, so thank you for this. Your explanation is very clear and concise and I understand now, so cheers for that.
I just have a habit of over engineering everything, but I guess it’s fair enough to only really worry about it later. But alright, I’ll scrap the idea if it isn’t necessary. And if it turns out that I need something like that later on, then I’ll look into it then.
I think I recall reading about this some time ago. I’ll definitely go through that thread, so cheers again for linking it.
If you worry about overengineering, then maybe instead of thinking of game development that “Coins clicking simulator” is the only and single continuos project, you might think like “Coins clicking simulator - MVP” and then “Coins clicking simulator - Beta” ect. so you see that for instance “i’m making MVP, so i don’t need memory collection, but i need gui that when you click it gives you how much coins you have” ect. this might help you a little