So, my game's memory usage gets higher, despite all extra parts being added being removed. The game can be found here (https://www.roblox.com/games/575337434/Winter-Crisis-DEMO#!/about), not uncopylocked, but what ever.
The game does involve inserting AI, which are all controlled by a central script, there is a cap on the AI in game at once though, and they do clean up. Each one is given a seperate coroutine if that is relevant. Script usage does not go up, but memory usage goes up VERY rapidly often into 3-4GB late game, this causes obvious problems.
Another thing is that some AI have special powers, such as the ability to set fire to you. This admittedly is scripted rather lazily just by insert a fire into the player, which has a script which is it's child, and is enabled when cloned in. It'll damage the player once a second for 10 seconds, before deleting it's self.
The AI's health was also scripted rather lazily as another scripter who worked on it (but tended to do other bits of the project than the AI), and it has Roblox humanoid to move it, but we also set the health of the humanoid to match the health of the core health value of the mob. This is done by using a separate script, which is removed by using :Delete() on the entire mob when it has been killed.
Can any of these things (some of which are admittedly bad practice lol), cause memory leaks? If not, what else might the issue be. CPU and GPU performance stats stay fairly constant throughout the game, as well as send, receive, and physics
Do not use Delete or remove to delete parts. Use :Destroy() instead. Remove just parents the object to nil, still keeping it in memory but making it inaccessible.
Destroy parents it to nil and then queues garbage collection IIRC.
In other words, always use part:Destroy() because it actually deletes things unlike remove
Another thing is to check the log for print loops. Remove lines that print something every iteration because that takes up memory too.
*Also make sure you dont happen to have a Lua virus because they eat up memory. Typically you get these from one infected model and then when you play the script clones itself like crazy. *
Depending on how your central AI script stores the AI, it might not be releasing the references to the AIs, meaning that the garbage collection can never reclaim that memory.
Here's an example of a memory leak:
ais = {} numAIs = 0 function Add(ai) ais[ai] = true numAIs = numAIs + 1 end function Remove(ai) ai:Destroy() numAIs = numAIs - 1 end
"Destroy" doesn't actually destroy something from memory, it just sets the parent to nil (and forces it to remain nil) and cleans up events connected to the part you've destroyed.
In lua, memory is only reclaimed when there are no more references to the object OR the only references are "weak". Thus, there are two ways to fix the memory leak in the above script:
ais
table. Add ais[ai] = nil
as the first line in the 'Remove' function.ais
a weak table: ais = setmetatable({}, {__mode="k"})
. Note that "k" means "weak keys", "v" means "weak values", and "kv" means "weak keys and values". If you assign ais like this: "ais[#ais+1] = ai", then you would want weak values, since 'ai' is then being used as a value.You can read up more on weak tables here.
Note: I am fairly certain a script deleting itself shouldn't be able to create a memory leak unless it's added references to other scripts or the workspace. (So, if it just adds an effect for 10 seconds and then deletes the effect and itself, it won't create a memory leak.)