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…
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.
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.
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
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.
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