Objects still exist after being :Destroyed() and set to nil?

I am currently struggling with it.
Here’s an example script:

local objval = workspace.ObjValue
local part = Instance.new("Part")
objval.Value = part
part:Destroy()
part = nil
if objval.Value ~= nil then
        print('This is not supposed to be printed.') --This prints this? Bruh
else
        print('This has to be printed!')
end

image

It is because the objval.Value is not really nil, what you made nil again is the part, you’ve set the objval.Value when this variable “part” is not yet destroyed, so it’s natural for the value to not be nil if you aren’t setting it nil, I think this script would help you:

local objval = workspace.ObjValue
local part = Instance.new("Part")
objval.Value = part
part:Destroy()
objval.Value= nil
if objval.Value ~= nil then
        print('This is not supposed to be printed.') --This prints this? Bruh
else
        print('This has to be printed!')
end

This isn’t the solution I’m looking forward to. Because I’m actually doing this on two scripts.
One that detects when the ObjValue.Value is nil or still exist or not.
One that deletes the part that the ObjValue.Value is holding.

You shouldn’t have any need to know wether an object still exists in memory after you delete it, in any case objects won’t get garbage collected as long as there still exist a reference somewhere which prevents the object from being garbagecollected.
With your code the part won’t get garbage collected since the object value holds a reference to it which in turn gets referenced by your code.

If you want to keep track of objects you deleted you have to use “weak tables”, which are just like normal tables except that the garbage collector ignores references in this table when deciding on wether or not an object can be wiped from your memory.

For example:

local t = {}
setmetatable(t, {__mode = "v"}) --the table is now "weak"
 
local part = Instance.new("Part", workspace)
t[1] = part
part:Destroy()
part = nil

repeat
	if t[1] then
        print('The Part has not been garbagecollected yet') 
	end 
	wait()
until t[1] == nil

if t[1] then
    print('The Part somehow has not been garbagecollected') 
else
    print('The Part has been successfully garbagecollected')
end 

An in-depth article also exist on the wiki if you want to read up on it:

7 Likes

It will exist until all references go away (or the references are weak…but you have to explicitly configure that per metatable).

In other words, if you can still observe the object anywhere, it will stick around. Once it’s alone with no one left to contact, then it will be picked up and deleted by the garbage collector.

It’s a sad and lonely end.

9 Likes

Maybe this is happening because you are setting the part to nil, but the value of the objval is not being updated.

So, the actual object is destroyed, but not the value of the value.

First, you should mention that ObjectValue.Value is a weak reference (it seemed like you already knew this, but it isn’t common knowledge).

Next, your code is fine, except that it doesn’t give the garbage collector a chance to run. Putting the check inside a loop reveals that it works.

while objval.Value ~= nil do
    print("Still exists")
    wait()
end
print("No longer exists")

Also worth noting is that events like Changed wont be fired when the value is garbage collected. Polling is the only real option.

4 Likes

ya i know i am face same problem bro

I know I’m late to this, but I’m having the same problem, and the value never turns nil despite checking on a loop.

In my game, player1 picks up player2, and then a script in player2 makes it so player2 gets dropped if player1’s root part is nil. But it never turns nil. The objectvalue keeps insisting that player1’s HumanoidRootPart still exists, aswell as that player1 still exists, even after removing them from the game. No matter how long I have the script on a loop, it still returns that the root is not nil.
(It simply puts the objectvalue’s value to the rootpart, and checks if the value is nil or not.)

1 Like

If yall don’t know how it happened, here is an example:
NOTE: The object value Humanoid is part of the Character which is me who is the user who created a clone, but for some reason it didn’t detect that the humanoid didnt exists after the character was removed. (Don’t forget I already tried using my Character as object value.)
https://i.gyazo.com/ace3c8c27ff351739a9d19690f008c77.gif

Check if the parent of the value is equal to nil.

image

image