"Cleaning up" an OOP class & concerns with long-time use

I’ve been using OOP in my game for a little while on systems that benefit from using it. One of these systems is my building system. Each time a new building is supposed to be created, I run Build.new() with some arguments and it creates the world model along with the build OOP object. This object has the useful methods for damaging the build, editing the appearance, and much more. This object is then stored in a big array of all the builds in the game. Whenever I want to get the OOP class of a given build and run a method, I would do that like so: Builds[buildWorldModel]:DoSomething().

I’ve began to wonder if there should be a more significant cleanup process however, to avoid memory being used on, basically, a non-existent object. When a build gets destroyed, all it does is delete the model and remove itself from the array of the builds in the game. Is there more cleanup I’d have to do here?

On that note, would there be a downside to this system if players were using the build feature constantly for hours without any server restarts?

I recommend using a maid . Maids are classes that can hold table values, instances, and connections. You instantiate a new one in each object with maid.new(). This allows you to add all connections, instances, and values to the table. When you call a Destroy() method on your class, call the Destroy() method on the maid class as well. This will automatically clean up all data.

See more here:
http://quenty.github.io/api/classes/Maid.html
Made by @Quenty

7 Likes

At the moment, I’m already using maids for my event connections. Would adding the class into the maid and cleaning supposedly delete the whole class in the way mentioned?

It doesn’t actually help you figure out what needs to be cleaned up. It just makes it easier to make sure that the things you choose get cleaned up when you choose.

Try posting your code so we can give it a look.

Well as far as I know, the only things that need to be cleaned up are already cleaned up. I guess the main point I was trying to get at in my original post was do I need to cleanup the class itself? After the world model is destroyed and it gets removed from my list of buildings, is the class taking up memory by just sitting there?

Do you mean the instance? Yes, that needs to be cleaned up. Specifically, you need to make sure no strong references to it exist after it’s destroyed.

What do you specifically mean when you say instance?

Classes are blueprints for creating objects. Objects made from the blueprint that a class defines are called instances. Calling Class.New creates a new instance of that class.

The class should almost certainly exist for the whole lifetime of the game. So it doesn’t get cleaned up, except for when the game stops, and that’s done automatically for you by the Roblox engine.

Some instances can be destroyed. When an instance is destroyed during the run time of the game, it needs to be cleaned up to prevent a memory leak.

It’s still a bit unclear what you’re trying to say. Keeping it basic, do I need to cleanup the class, and if that’s the case, then how?

Post your code and tell me what you mean by “the class”.

Without sending hundreds of lines of code, this is basically what the structure is:

Build = {}
Build.__index = Build

function Build.new()
	local newBuild = {}
	setmetatable(newBuild, Build)

	--setup stuff
	
	BuildsList[newBuild.Model] = newBuild --Add this to the list of all builds
	
	return newBuild
end

function Build:Destroy()
	BuildsList[self.Model] = nil --Remove the reference to this from builds

	--more cleanup stuff
end

And by class, I mean what’s returned from Build.new(). FYI: I am still somewhat new to OOP on Roblox, as I’ve only been working with it seriously for a few months.

Build is the class. What’s returned by Build.New() is an instance of the class, or an object.

The way you’re removing references to the instance when it gets destroyed is correct. When there are no more references to it, it automatically gets garbage collected at some point.

What exactly counts as a reference?

Let’s say the server was doing this somewhere, lets say, inside of an event connection, not in the global scope of the script:

local build = BuildsList[model]
build:DoSomething()

Would I need to do any manual garbage collection on references like that?

If that’s the entire contents of the script, then no. At the end of the script, the build variable goes out of scope so that reference stops existing.

If that’s supposed to be inside the listener for an event connection, then the connection and the listener may or may not get cleaned up automatically. If it doesn’t get cleaned up, then build may not get cleaned up and yeah, you’d have a reference hang around forever.

You can see when you can get memory leaks from events here:

If that code was inside of a .OnServerEvent connection would it cause memory issues?