Properly destroying an OOP object

I’m currently learning about Object Oriented Programming and I’ve stumbled upon a problem. Whenever I’m destroying an object all variables that reference the object are not set to nil. I tried setting self to nil but the variables still reference my object. Here’s my code:

Module Script:

local ServerScriptService = game:GetService("ServerScriptService")

local Modules = ServerScriptService.Modules
local Janitor = require(Modules.Janitor)
local Signal = require(Modules.Signal)

local Object = {}

Object.__index = Object

function Object.new()
	local self = {}

	setmetatable(self, Object)

	self._Janitor = Janitor.new()
	self.Signal = self._Janitor:Add(Signal.new(),"DisconnectAll")

	return self
end

function Object:Destroy()
	self._Janitor:Destroy()
	table.clear(self)
	setmetatable(self, nil)
	self = nil
end

return Object

Server Script:

local ServerScriptService = game:GetService("ServerScriptService")

local Modules = ServerScriptService.Modules
local Object = require(Modules.Object)

local newObject = Object.new()

print(newObject) --> table

newObject:Destroy()

print(newObject) --> empty table

Is there a way (apart from doing newObject = nil when an object is destroyed) to set all variables to nil that reference the object? If I’m understanding correctly the object doesn’t get garbage collected if I don’t do that.

That’s all you can do. That table will be there whatever you do. Don’t worry, if you worrying about memory leak, it doesn’t.

2 Likes

According to Wikipedia “A memory leak may also happen when an object is stored in memory but cannot be accessed by the running code (i.e. unreachable memory)” which is the case here if I don’t manually set newObject to nil. Am I getting something wrong here?

Roblox doesnt provide much tools for this.

My Tl;DR after reading is to destroy instances and connections. Other data types do not typically matter as after the variables are no long used it will be cleaned up. This means you only need to worry about it if there is an infinite loop and data keeps being created and stored in a table or creating instances and storing them in workspace.

Example testing, seems like :Destroy is not needed perhaps its an internal Roblox optimization? Safer to make sure the instances are destroyed with a function.

1 Like

Thank you for your response and for linking the posts. It helped me understand garbage collection way better. One more question: How would I test my code for memory leaks?

1 Like

I’ve seen this in your 2nd linked post but how can I tell from the graph that my code is leaking memory?

If it’s leaking the graph will keep on increasing.

You can try this example of a memory leak:

--A real memory leak example
debug.setmemorycategory("Table with too many parts")

local untrackedtable = {}
game:GetService("RunService").Heartbeat:Connect(function(deltaTime)
	table.insert(untrackedtable,Instance.new("Part"))
end)
1 Like

Thank you for your help. I think I’ve got it now. I marked your first post as a solution

1 Like

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