Memory Optimisation| Root Causes | How to optimise memory

This topic definitely wasn’t the best and I’ve created a much better version which actually has some time and effort put into it, and it is this topic.

Memory usage can slow down games, disconnect players and make players leave your game. Memory usages are also really hard to identify. Be warned since this topic may be long.
Also a quick reminder, if your game is running badly on ROBLOX studio, it’ll run way better on the game itself. Roblox studio is known to use 3X more memory so if that’s your problem, you have it fixed. This topic will go through a series of ways to optimize your memory and it’ll give you a better understanding of memory usage.

To check your memory usage, press F9 and click memory:


This is not my game so you may have more to view if your a developer of a game.

MEMORY USAGE


(some lazy image I made)
Memory usage is determined by the status of your memory. For example, a high MB amount such as 32 is considered as a lot of garbage. Luckily, there is a garbage collector but some data won’t be collected. Memory usage is when a script runs too much data. When this happens, the memory won’t be able to handle the excess data and hence, it’s referred to as “garbage”. When this happens, it’ll collect up and eventually, this will flatten connections between the server and the client because of the amount of garbage getting perceived by the client.

ROOT CAUSES

Too much scripts can use too much data/memory. Scripts contain data on their source(the script and what it runs), name and class name and every property. Too much scripts will run on the memory and start producing too much data on the memory and thus, using too much memory. Too much parts also will be the root problem since each part has data for it’s properties, appearance, mesh and etc. Exploiters can also be the reason since their exploits run a LOT of data. Too much tools in starter pack will need to be replicated to the backpack and thus, using a lot of memory since your replicating data. Too much loops in your script is also a common reason since it runs data MANY times on the memory. Only use loops when you cannot do an alternative script. Now also a common mistake I see some do is parent a part before the properties are set. You may ask, Why will this use a lot of data?? Now the main reason is that the script has to check EVERY time if the part is there and thus, it uses data. Now, lets show you a demonstration of multiple codes that can heavily defect your memory usage.

    while true do
wait(0.1)
   local player = game.Players:GetChildren()
   if player == nil then
    print("No player!")
 else
   print(player.Name .. " is in the game!")
     if player.Name == "exp_lol123" then
print("exp_lol123 is in the game!")
end
     end
   end

This code will use a lot of memory.
Code below will be the alternative better way with much less usage of data.—>

      game.Players.PlayerAdded:Connect(function(player)
  if player.Name == "exp_lol123" then
print("exp_lol123 is in the game!")
   end
end)

This is a much better way and uses A LOT less memory. Here’s another example of code that uses unnesscerary amounts of memory:

while true do
wait(0.01)
if script.Value.Value ~0 then
print("Changed")
end
end

Much better practise:

script.Value.Changed:Connect(function()
print("Changed")
end)

Here’s another example, for this example what’s happening is your parenting the part to nil which you think would delete the part but in reality, the part will still use memory. Build up of this will lag your game. A part lying around like this will use memory, here’s the bad practise:

local part = workspace.Part
part.Parent = nil

Better practise:

local part = workspace.Part
part:Destroy()

Finally, disconnecting a connection. Disconnecting a connection is pretty useful since connections that are still lying around still use memory if not disconnected. This will start to cause lag problems in your games so you should never leave a connection disconnected. Here’s how:

    local connection = game.Players.PlayerAdded:Connect(function(player)
 print(player.Name .. " has joined!")
      connection:Disconnect()
   end)


(another lazy image I made)

FIXING ROOT CAUSES

Now we’ve figured out how to find root causes, how about how to fix them. Let’s start with the easiest, parts. Too many parts can lead to high memory usage but the amounts may have to be in the extreme. Unions can lower memory usage but not to the extreme. Model be great for optimizing parts(which is not this topic) so let’s move on. Let’s also now start with too many scripts. Shortening or simplifying scripts can be essential for memory usage drops. I’ve currently experienced a problem where my script was too long but with continuing the script on with another script, everything worked perfectly fine. Loops can go hard on your memory so if it’s appropriate for what you’re doing, convert them.

Why FPS is lowered because of this

FPS is probably the main key we worry about so let’s look into why FPS is lowered. Well, it’s all on communication. Communication between the server and the client transfers essential information such as scripts onto the client to render. Sometimes, garbage builds up and is mistakenly transferred which overtime, leads to more things that need to be rendered but is completely unnesscerary which lowers FPS.

Now this topic is a little long and I don’t think some of you bothered to read it but as I said above, this topic is supposed to be long since the memory is confusing. Anyways, I hope you found this useful and if there are any wrong parts, please tell me in the replies but with that out of the way, we’ve finished this topic!

23 Likes

How will this cause a memory leak? (ignoring the fact that the script will error)

This isn’t correct. According to wikipedia the definition is:

a memory leak is a type of resource leak that occurs when a computer program incorrectly manages memory allocations[1] in a way that memory which is no longer needed is not released.

6 Likes

Wait a second, is it okay if I change the name to clear any confusion?

1 Like

If it fits what it is that you are explaining.

1 Like

As stated by @Jhxan, this isn’t a memory leak, it is just a very memory intensive script due to how it’s looping through every player and running multiple if statements.

This script in theory would cause a heavy, but constant usage of memory (scaling with the number of players), whereas an actual memory leak would, over time, have increasing memory usage until memory eventually caps out on the server or client depending on where the memory leak is located.

3 Likes

None of what you’re talking about here refers to memory leaks, you are simply talking about memory optimization, but even then unfortunately it doesn’t seem like you really know what you’re talking about.

This statement is incorrect, other users above have explained what memory leaks actually are. Exploiters cannot cause memory leaks for other players, only themselves which at that point is none of your business. If they can, your code is faulty.


Further, some of the information and advice you give here is not correct.

This is not true; loops are fine to use provided you are not making redundant expensive function calls, or your logic is wasteful. Splitting up the same logic between multiple scripts somehow is likely to create more problems.

This is also incorrect. Simplified, the actual reason why you should parent last is that extra processing can happen on parts currently in the datamodel when you change properties. If you set the properties before parenting the part, you avoid this.

Also not sure what your example about returning data is supposed to mean. It seems like you’re just inventing a problem by doing something that doesn’t make sense. In some cases it may be cleaner to have functions that operate on variables in a higher scope (e.g. a variable global to the script) instead of returning a value, but the reason for doing this is most often organizational. You may get some performance out of it, but it seems negligible compared to the rest of the overhead involved in Lua (see: micro-optimization), you’d get better performance improvements by writing smarter code, even if that code uses functions that return values instead of using higher scope variables.

This is not universally true, unions contain history about everything that went into making them, and must be downloaded when users join the game. They don’t always magically improve your memory usage, and come with a lot of caveats that impact how your game behaves. If you have many separate instances part of a common construction, it may be better to union them to reduce the number of instances and simplify working with the construction, but this is not a magic bullet for memory problems, and is suited mostly to niche cases.

I don’t know what you’re trying to say here. Models and folders are organizational tools. Models have some properties available that are useful for streaming enabled games, but these are for improving the appearance of the game when the world is streamed out, not improving memory usage.

I think this is irresponsible to suggest without further detail. You never “merge” scripts, you should write code that only requires one script to operate on however many instances as necessary.

E.g. you can use CollectionService to tag all of the parts in your game that should hurt the player, and use one script to attach connections to those parts and run the logic, instead of having one script per part. However, I’m not sure if this is so much a performance improvement as it is good practice; doing this is way more maintainable and easy to work with if you need to modify the code.

Exploiters cannot typically impact memory usage for anyone but themselves, unless they are abusing your code through your remote events. There are many resources on this forum for how to write more secure remote code. By spamming remotes they can sometimes cause problems, but if your code handles this gracefully, these problems are out of your hands.

This section is not correct. A lot of memory-intensive processing has nothing to do with rendering. Further, there are many other reasons why high memory usage is not good, the biggest being causing crashes on mobile devices, and causing general performance problems; if a user runs out of memory on their desktop, they can start using virtual memory which is significantly slower.

This… is mostly irrelevant. You can offload processing to client or server to save on memory usage sure, but this is a design problem; you should make intelligent decisions about how and when to change where processing happens. Blindly moving code will not solve anything.

6 Likes

I figured I would through my two cents in here. The other people who responded gave a pretty in depth review, but here is a more focused explanation. Memory leaks refer to when you have memory allocated that is no longer being used. It doesn’t necessarily refer to otherwise having too much memory being used.

You see memory leaks most often when working with events. When you use the :Connect() method on an event, it returns a RBXScriptConnection. The problem comes when you do not disconnect your events after you are no longer using them. According to Roblox:

Always call Disconnect() when a connection is no longer needed. Forgetting to do so can cause your game to use more resources than necessary. Note, however, that this may not always be necessary; when an object is destroyed, all connections to that object’s events are disconnected automatically.

As far as your explanation goes with loops, there is some truth to what you stated but you should probably write it differently. “Busy waiting” and “Event-driven programming” are two terms we use in the computer science world to better describe what you wrote. The loop you used as an example is an example of what we call “busy waiting”. You are asking the server every 100ms to check if a certain player has joined the game. Instead, you should be looking into “event-driven programming” and simply let the server tell you when the player has joined the game.

Lua is a high level scripting language and it’s very rare that you need to do any sort of busy waiting. I have heard that this sort of busy waiting is more common with low level programming languages like C, but I am not proficient enough with those languages to really give you a definitive answer there.

Hopefully this was helpful, if you have any questions feel free to reach out.

5 Likes

The title is creating way too much confusion so I’ve decided to change the title.

Guys, I’ve edited the post to clear any more confusion and I’ve implemented all you feedback. Thanks for the feedback!

1 Like

Cleared confusion by saying too much memory usage.

I’ve implemented all of your feedback, thanks a ton!

1 Like

Thanks for teaching me something!

1 Like

pls don’t kill me for bumping PLS

Now this is incorrect. Returning values uses unnoticeable amount of memory that won’t affect your game in ANY WAY. Do you know the definition of memory and what it’s used for? If you don’t, let me explain:

RAM, or random-access memory is used when an app writes down instructions to the CPU, so it could later execute them. Your loop example is correct, since you constantly need to write down instructions and temporarily store all the children of the Players service. The connection example is a much better practice, so you are correct on that. However, the problem with the return example is that it only needs to write down instructions to return once, which will not use any noticeable amount of memory.

3 Likes

I did say you can disagree with me for this one. Now I look at this, this is pretty useless. Since I’ve pretty much improved in my knowledge of this, I now understand why I shouldn’t have had this.

2 Likes

I think you were supposed to reply on a different topic.

1 Like