Is everything garbage collected in this module?

Soo, i’ve run this module about 100k times, and i found that in some runs memory grew about 1.5 GB, in others about 2-3 MB, i had to rewrite it many times, but i don’t know how i can prevent memory leaks, i’m scared that one of those tables is the cause but i don’t know how i can check that

local System = script.Parent

local ISOS = require(game:GetService("ReplicatedStorage").ISOS)
local Event = ISOS.Class({})

function Event:__init()
	self.Callbacks = {}
end

-- Connect bindable event (uncompatible with custom)
function Event:Bind(BindableEvent: RBXScriptSignal, Callback, ...)
	local Callbacks = self.Callbacks
	
	Callbacks[Callback] = BindableEvent:Connect(Callback, ...)
	return Callbacks[Callback]
end

-- Connect custom listener (uncompatible with bindables)
function Event:Connect(Callback: (any) -> any)
	local Callbacks = self.Callbacks
	if typeof(Callbacks[Callback]) == "RBXScriptConnection" then Callbacks[Callback]:Disconnect() end
	if typeof(Callbacks[Callback]) == "thread" then task.cancel(Callbacks[Callback]) end
		
	Callbacks[Callback] = true
	
	local connection = {}
	function connection:Disconnect()
		if typeof(Callbacks[Callback]) == "thread" then task.cancel(Callbacks[Callback]) end
		
		Callbacks[Callback] = nil
		connection.Disconnect = nil
	end
	
	return connection
end

-- Fire custom listener
function Event:Fire(...)
	local Callbacks = self.Callbacks
	for Callback in Callbacks do
		Callbacks[Callback] = task.spawn(Callback, ...)
	end
end

return Event

Also i have question: How do i’m supposed to detect memory leaks? for now i simply run code a lot of times with and without disconnect function to see if it works

2 Likes

You can always make your custom signal system, but I would recommend GoodSignal. Or at the very least, learn from goodsignal. Goodsignal is really good.

2 Likes

Ik, but i want to make my own one, i simply don’t know if i should worry about memory leaks here, i always was bad at that soo i want to ask

2 Likes

You can use debug.setmemorycategory to check where the memory leaks are.

You don’t have to use GoodSignal, but you can learn from it. A problem I can already see is that this script doesn’t use coroutines, or a custom runner thread.

But, there’s really no harm in goodsignal, I’ve went down your route once and it was very tedious. I struggled with performance. There’s really no point not to, well respected scripters and modules rely on good signal (RaycastHitbox, which is EXTREMELY performant.)
(Fastcast doesn’t tho, I think).

2 Likes

You mean my module don’t use corountines or that Good Signal doesn’t? also thx for debug methood

2 Likes

Your module doesn’t use coroutines, to open threads. Which, is already in base rbxscriptconnection (every signal opens a new thread in base rbxscriptconnection). Simply because of that, bindables have an advantage.

2 Likes

I used task library to create custom events that i fire manually when i need, i don’t need corountines as the only thing that i need is to create new thread and eventually destroy it

2 Likes