Is this Roblox's feature?

I’ve observed that very strange behavior happens when i use task.spawn functions with yield inside them

This is code inside a server script:

task.wait(8)

for i = 1, 100 do
	task.spawn(function()
		task.wait(1)
		print("hello")
	end)
end

As you can see, if there is task.wait() inside task.spawn, it will stay in registry, but it doesn’t look like memory leak, why?

task.wait(8)

for i = 1, 100 do
	task.spawn(function()
		task.wait(1)
		print("hello")
	end)
end

task.wait(2)

for i = 1, 100 do
	task.spawn(function()
		task.wait(1)
		print("hello")
	end)
end

Next part of code repeats this process twice, and still the registry added amount stays the same
I didn’t found anything about this, AI also doesn’t tell much, only that it’s possible optimization

My question is, is this memory leak or simply optimization, and how to counter it cuz if you made a lot of threads, they’ll stay here…

1 Like

I’m not 100% sure what you’re asking but these might be what you want to know:
The two anonymous functions contain the exact same code. They are also indistinguishable, theres no way for them to ever become different. The interpreter can optimize this by only loading the code once, and probably does.
Spawning a thread does not require duplicating the code, since the code itself is never changed. Instead, each thread requires a context to be stored, which contains only information required to pause and resume the thread. This context can be freed once the thread ends.
So, your code is loaded once, 200 contexts are created then eventually freed, so the only memory left over after execution is the code.

1 Like

I tested this with tables some time ago and performed same test today

task.wait(8)
print("hi")

for i = 1, 100 do
	task.spawn(function()
		task.wait(1)
		print("hi")
	end)
end
task.wait(2)
for i = 1, 100 do
	task.spawn(function()
		task.wait(1)
		local a = 5
		a += 1
	end)
end

task.wait(1)


print("hi")

This code also gives the same result, even if it’s different context

Similar thing happens with tables, when you remove index it will allocate some memory until you remove this table by setting it to nil, sadly i can’t remove task as they are handled internally

AI thinks that it’s because registries are expensive to operate, so they store some memory to optimize it

Task scheduler keeps yielded task.spawn threads in the registry until completion, but they are cleaned up afterward. I would assume it’s an optimization, not a memory leak.

1 Like

What if they completed and they are still here? Sorry that i ask but it seems strange that they do stay, but if new threads are created they take place of those previous ones, i only assume that roblox tries to reserve registry for new task.spawns because there is possibility they’ll be created again

1 Like

I’m not really sure it’s doing this on purpose and more using what is available. I’m no total expert here but, from what I researched they do clean up, just not on an exact timing. I’ve also looked at scripts purposefully designed to do what you just stated “take place of those previous ones”, leading me to believe this is not exactly what it’s doing by default.

1 Like

It’s maybe a bug, or garbage collector cleans them when needed, i’ve heard that removing/adding registries is very expensive, and because most devs use those threads with task.wait, i can assume it’s some sort of optimization that wouldn’t cause that much problem, thx for help anyways

From everything I’ve found on this subject looking around for you … it’s saying it’s not a leak it’s an optimization.

1 Like

I still don’t really know what you’re asking.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.