Hey all - I’m confused - did this change recently? In my server script, I destroy the scripts parent.
But my script continues to work as if it isn’t destroyed ?
How?
Hey all - I’m confused - did this change recently? In my server script, I destroy the scripts parent.
But my script continues to work as if it isn’t destroyed ?
How?
Its possible for the script to still be in memory if its referenced by something. Try calling :Remove() on the script or its parent instead. This behavior is similar for instances, if you set somethings parent to nil and no other script references it, it will be garbage collected eventually. If something does reference it, that script could at any time set its parent to non-nil again, so it cannot be safely garbage collected, and so it isn’t.
Sorry if this is a dumb question, but wouldn’t calling :Remove()
also not solve the “issue”?
“if its referenced by something”
What’s this mean exactly…I can code, so you aren’t speaking to a total noob… I’m not sure my script is “referenced by something” but I’m also unsure.
Thanks for your kind response. Appreciated!
Hm. I don’t typically use remove, I’m unfamiliar with it - I’ll check it out.
This wasn’t even intentional… I was reviewing the script and saw I put the
script.Parent:Destroy()
in the wrong spot in the code (derp!), but then I saw destroying the parent wasn’t stopping the script as I expected…so I had to wonder what was going on.
I spend so much time coding and designing that I have a hard time keeping up with developments in the engine/code framework. Thanks to both of you for mentioning this.
:Remove()
isn’t something I have used either, but from what I’ve heard it is something you should stay away from. :Destroy()
prepares things for garbage collection, but I don’t think :Remove()
does
For non-script instances, an instance is referenced by something if “anyone remembers it exists”. Under the hood, roblox is keeping track of how many places are referencing an instance. Actually I don’t know this for sure but I have reason to believe it. If you have a server script that contains something like:
local myPart = workspace.Part1
And one script sets Part1’s parent to nil, it will no longer be in the workspace, but it will not be removed from memory. Garbage collection by definition only removes things that cannot possibly be used anymore, however the myPart variable still remembers the part. Until this variable goes away, the garbage collector is not allowed to remove the instance. If this variable is a global variable (defined in the top level scope of the script), it will never go away unless the script itself is destroyed. Remove() bypasses this and tells the GC that you intend for this thing to be collected. I believe Destroy() goes an extra step and prevent anyone else from reviving the object between when you call it and when its actually removed. You should always use Remove() or Destroy() when your intention is to permanently remove something. I have done the method of setting Parent = nil exactly once recently, and my reason was they were ViewportFrames containing expense to generate thumbnails that I didn’t want removed permanently. I would keep them in a table instead (someone knows about them, so they won’t be collected), and restore them when the thumbnail was needed again.
Edit: I double checked the documentation and it seems Destroy() is preferred and Remove() is being phased out. Also Destroy() does not guarantee that all references are destroyed, but it will most likely cause a downstream error if you try to use the object, which will point you to the issue instead of just silently causing a memory leak.
Thanks for the explanation. I get it. Really appreciate it.
I’ll check my code and see if this is happening.
Thanks!
You should also check to see if that ‘destroy’ section of script is being run, and that the Part is actually being destroyed.
Something like 'print(“parent Part destroyed”) right before the destroy line of code.
Thanks much, Scottifly. I did in fact use print statements, as you direct.
You can also tell it’s still running, because in the section after the “destroy” call, things are .parented out of replicated into workspace and stuff - and that stuff is happening.
In a way, it’s not an issue, because I don’t even need the destroy in that particular spot - I moved it farther down in the code already.
I mostly posted because I thought:
if you destroy the parent of a script, the script will also be destroyed, and it will not finish any of its commands.
This happened by accident in my code, I saw the results, and was wondering “Did 1(above) change ?”
Responses have been great. Thanks all.