Using instance objects as keys in tables and preventing memory leaks after deleting data in the table - it won't leak afterwards right?

Hello,

Given a table, using an instance as the key:

local testPart = Instance.new(“Part”)
local testTable = {}
testTable[testPart] = {
anotherPart = testPart:Clone()
}

If I delete like so:

testTable[testPart].anotherPart:Destroy()
testPart:Destroy()

It should not memory leak correct? I have read that when instances are used as keys, the keys itself uses the instance’s ID on the backend. Since I have deleted both instances, it should be no problem right? The key itself is supposedly converted into a string ID from my research.

I decided to make this new topic since it is so specific and I did try to search about this but most replies regarding this wasn’t very clear into the specifics. Just wanted to clarify it completely, what I have understood about this is correct???

4 Likes

Seems correct to me. Maybe for extra measures you could set the key to nil.

1 Like

Make no mistake, you will leak memory if the instance is still able to be referenced by Lua. Destroying the instance is only half of the story.

3 Likes

What? I use the :Destroy method, eventually won’t Lua detect this as unused and clear it for me??? The only presence the instance has in this case is the key however in the Lua backend, that key should be converted to a string ID (based on what I’ve read) so it shouldn’t play much of a role in terms of memory leak.

Where are you seeing the memory leak in this case???

Hello all,

This is considered fixed. In order for Lua to garbage collect, there must be NO references meaning NO keyed index should be able to be referenced. If there is even one reference, it introduces the chances of your data not being properly garbage collected or even garbage collected at all!

Just learned that after talking to some people.

Use table.clear() on your objects and data just to be safe!

I’ll go into more detail regarding what Instance:Destroy() does and what it does not:

What it does do:

  • Disconnects every connection
  • Sets the Parent property to nil and locks it there. This guarantees that no future references to the instance can be obtained via the DataModel (aka the game global).

What it does not do:

  • It does not automatically free the instance from memory / clear any lua references to the instance.

You’re probably wondering why it is that :Destroy() doesn’t automatically clear lua references, especially given the fact that you only really call :Destroy() when you’re done with the instance.

The answer is rather simple, the consumer (script using the instance) of the instance bears the responsibility of concluding their use of the instance.


Bottom line: Lua has garbage collection for a reason.

3 Likes

Love to see it.

And let’s clarify a bit more of the nuances here:

For reference:

Beautiful answers to nuances for reference in regards to this topic.

1 Like

When I read/write code, it comes second nature to me as to whether or not there’s memory leaks, of course, it’s not always that easy, but usually it is. I assume it’s like that for others, but I can’t be sure.

With that being said, you can think of references like a linked list where clearing a reference means you just discarded your only way of accessing everything thereafter. You can think of it like a train, if you detach one car, you lose everything linked to that one.

The king of memory leaks is RbxScriptConnection.

Devs hate this one simple trick:
Create any instance, don’t parent it anywhere, call :Connect() on one of its events. Now if you lose a reference to the instance or the connection you created, you don’t have to worry about it being deallocated by the garbage collector!

No surprise there as this is expected, its the consumer who has the responsibility of concluding their use of an instance. An active connection is a reference.

2 Likes

I think i get what Luau tables are, they can store Booleans, Numbers, Strings and Functions.

This one script helped me get a handle on Luau tables.

local testArray = {“A string”, 3.14159, workspace.Camera}

print(testArray)

To make one table you do
local Test = {“String”, false}

print(Test)

Do not report this.

1 Like

lol, no worries.

Yes, that’s a table, specifically an array.

Yes, that’s a table, specifically an array.
Do note that False is not the same as the primitive false.

oh, sorry about that i got misinput from my brain and i put “False” when it was “false”

1 Like

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