I’m working on a module that would allow me to smoothly change the transparency of a frame and its descendants because a CanvasGroup can be blurry at times. I want to be able to insert many, many frames, then delete them without causing any memory leaks in my script.
I start my test off to see if there are any memory leaks by collecting information about the script and its memory consumption before adding the frames in. Next, I add 100 frames into a frame to test. The memory spikes because I make connections to detect if a property changes and an attribute with a specific name. After, I add all the frames, I wait for about 7 seconds: enough time for the memory consumption to appear on the graph. When this time elapses, I delete all 100 of the frames. Instead of returning to the amount of memory used before, the amount stays higher.
0.005 MB before adding frames - 0.133 MB with the frames added - 0.011 MB after the frames are deleted via the explorer.
Values before and after adding 100 frames to a frame.
All connections created within the module are put into the table shown below.
LocalScript code
if not (game:IsLoaded()) then
game.Loaded:Wait()
end
local UserInputService = game:GetService("UserInputService")
local Module = require(script.UIManager)
local Grouping = Module:Create(script.Parent)
local TweenInfo1 = TweenInfo.new(1.5, Enum.EasingStyle.Sine, Enum.EasingDirection.InOut)
Module = nil
UserInputService.InputBegan:Connect(function(Input)
if Input.KeyCode == Enum.KeyCode.E then
print("-------------------------------------------")
print(Module)
print(Grouping)
print(TweenInfo1)
print("-------------------------------------------")
end
end)
Snipit of code from the module responsible for making connections.
For context, Master
is the table seen in the output above, :Clean()
is a function used to disconnect functions and destroy the table seen in the output, and InputUi
is the frame I am adding all the frames into when I test.
local function Find(Input)
if table.find(Classes, Input.ClassName) then
local Attribute = Input:GetAttribute("ControlGroup")
if Attribute and typeof(Attribute) == "string" and Attribute ~= "" then
Attribute = string.gsub(Attribute, " ", "")
Master.Formation[Input] = {}
for Index, Value in pairs(string.split(Attribute, ",")) do
local Success, Result = pcall(function()
return Input[Value]
end)
if Success and typeof(Result) == "number" then
table.insert(Master.Formation[Input], Value)
else
print("Dropped request to associate "..Input.Name.. " with " .. Value)
end
end
return true
else
return false
end
end
end
local function DestroyConnection(ID)
Master.Connections[ID]:Disconnect()
Master.Connections[ID] = nil
end
Find(InputUi)
for Index, Value in pairs(InputUi:GetDescendants()) do
Find(Value)
end
table.insert(Master.Connections, InputUi.DescendantAdded:Connect(function(Identity)
if not (Find(Identity)) then
Master.Connections[Identity] = Identity.Changed:Connect(function(Property)
if (Property == "Attributes" and Find(Identity)) then
DestroyConnection(Identity)
end
end)
end
end))
table.insert(Master.Connections, InputUi.DescendantRemoving:Connect(function(Identity)
if Master.Connections[Identity] then
DestroyConnection(Identity)
end
end))
table.insert(Master.Connections, InputUi:GetPropertyChangedSignal("Parent"):Connect(function()
if InputUi.Parent == nil then
UiManager:Clean(InputUi)
end
end))
I have tried looking through the code in the ModuleScript and LocalScript trying to find the source of the problem, taking out pieces of the code every time I test it. It seems like the problem might be out of my control as I am running Roblox Studio on a mac under Rosetta 2 and frequently see memory usage in the 4GB+ range with it climbing just from keeping studio open.