[ROBLOX CRITICAL] Client Memory Leak with FilteringEnabled

I am not entirely certain, but I believe that I the issue that I’ve encountered is a ROBLOX client bug.

A memory leak seems to occur when creating large amounts of parts on the client with FilteringEnabled, even when those parts are destroyed and references are removed. I encountered the memory leak in my newest game, Astro Academy, another collaboration with @Crykee. The game implements the quick construction/destruction of a lot of models, and despite the appropriate destruction of the models and removal of references, a memory leak is occurring that causes players to crash after making several flights.

I have attached a place file with two identical scripts. One is a server script in Workspace, and the other is a local script inside of StarterGui. The code generates 50 parts and adds them to an array, and then destroys all the parts and removes them from the array after a wait().


Testing

Test by opening your task manager (windows users), going to the processes tab, and then starting a test server with 1 player. The value in the memory tab under the client process continues to increase. NOTE: This ONLY occurs when the local script is enabled and the server script is disabled. When the server script is enabled and the local script is disabled, the memory leak does not occur. This is the main reason why I believe this is a ROBLOX bug and not a code-related issue.
This test place will not cause any crashes due to the small number of parts generated, but it is clear that there is an issue.

Image of Task Manager ![blob.png](upload://AafmUUa739lxF9SYycCnDPk0aZw.png)

I do not think that it is the code that is causing a memory leak, but if it is, please let me know! I have never experienced memory leaks with my code before, so I am unsure if this is my fault or a ROBLOX bug.


Repro Place File

MemoryLeak.rbxl (10.9 KB)

14 Likes

Can I get some sort of confirmation that other people experience this too, or maybe a word from an admin that this is being looked into? This is a big deal, and could lead to extensive crashing if people are not aware of it.

Added ROBLOX CRITICAL tag to title to reflect severity. Normally I would never bump a post – especially not twice – but the fact that this bug can cause frequent crashes (one user said they were blue-screened by the game, unsure if that is related) and it has been 3 days with no response at all seems to merit a bump to gain the attention of staff.

I didn’t notice a memory leak when running your repro. I also tried it with 10x more parts. If there is a memory leak, it isn’t a roblox-critical-worthy one, unless it’s hardware-specific or something.

Have you tried recycling parts and models? Are you certain they’re crashing because of memory problems?

I recommend opening the flood gates on your paid alpha so you can get more data.

edit: it looks like it leaks a few hundred kb per second

1 Like

We let the game open for an hour today for free, probably going to do more events of a similar nature in the future :slight_smile:

I experience the leak, and we’ve talked first hand to 5+ players that also have the problem (As the current tactic is to actually rejoin the game every round because of the leak haha). Studio’s memory usage constantly increases until the point of crash. You need to make sure you’re looking at the Roblox Studio process that is running the local player, as well as making sure you started a server rather than playing solo.

Very surprised that you did not experience a memory leak with the repro. After about 2 minutes of running a test server with 1 player, the client instance consumes about 300mb of memory, and it consistently increases.

I’ve been working on recycling parts and models, but that system is causing some additional problems that I’m having trouble working out.

Astro Academy usually does not consume enough ram to crash the game until about 4 hours of gameplay for a first time player on respectable hardware (mere minutes for hardcore users). If more people respond to this thread saying that they don’t experience the leak, I may open the floodgates to collect more data.

I’m guessing your game only creates models that are on screen?
You should definitely leave models in a recycle table for maybe 10 seconds or so before you actually delete them, and when the model is used again, re-cframe it.

That’s essentially what I’m doing now. It eliminates the leak, but for some reason causes crippling lag at about 100k studs. Probably a quirk in my code, going to keep investigating.

It would be interesting if you reset everything to the origin every few thousand studs, or moved the map instead of the character

I’ve been considering that, and it’s definitely on my list of things to try. The reason I haven’t done that yet is because the game version with the leak in it does not lag at long distances, which is why I think it’s an issue with my code. I’ll try moving the map and keeping the character central next, though.

Definitely confirmed. I’m taking a look at this right now.

7 Likes

Update:
I found the problem in about an hour, but took over a day of work to properly figure out how to fix it. Basically, if you have Filtering Enabled and create parts on the Client, they will NEVER be freed from memory, not until you close the Client (Teleport OR close game).

Apparently there is a contract in ROBLOX where a Client has to verify with the server that a part has ALSO been deleted from the server before freeing the memory for Replication reasons. Apparently when Filtering Enabled was introduced, it blocked replication of the part to the server and the server was never able to acknowledge the delete events. Because of this, the Client hung on the part instance in the void FOREVER in case the server decided to send replication data about it.

I put a fix in for this yesterday. It should arrive next Thursday. In the mean time, be wary of spawning lots and lots of parts on the Client with Filtering Enabled, because they will never free from Memory. Thanks for the report, because this was some scary stuff.

31 Likes

Glad to hear this bug got filtered through quickly. This would explain the FPS drop people have said they get over time in phantom forces, probably the reason.

3 Likes

I want to add another piece of information about how Memory works in Filtering Enabled scenarios.

SPAWNING PARTS ON THE SERVER + DELETING THEM ON CLIENT WITH FE ENABLED
Please note that this will NOT free up extra memory on the Client. If you spawn a part on the server and then delete it on the Client, you will get a performance increase due to rendering load being lowered, but you will not get Memory savings. Basically, if you spawn a part on the Server, the contract is maintained where the part will stay in memory for Replication purposes even if it is deleted from the world on the Client.

This is because the Server does NOT know that you deleted this part and will continue informing the Client about any property/position changes even if they have no effect.

My fix involved NOT ADDING locally created parts with Filtering Enabled to replication data, making it’s lifetime in memory only depend on any Lua bindings and references to game containers.

7 Likes

Why does the deleted part stay in memory if property replications have no effect?
Is it because the server can change the Parent, which makes it be reparented on the client?
(which would be weird, as :Destroy() locks the Parent property)

Can’t :Destroy() clientside basically remove the part from memory and ignore replications?
If you call :Destroy(), you expect the part to never be reparented to something.

(I say “part” but I assume this is for every instance)

EDIT: just not sure what would happen if the server parents it to nil and back to a replicated storage.
(or first parents it to a non-replicating object, like ServerStorage)
I assume that, as it goes from not-replicating to replicating, it completely replicates to the client again.
That would remake the objects on the client, even though :Destroy() might be called on them earlier.
(although, unless you kept a Lua reference, you have no idea the objects are the same as those earlier)

You can experiment with this stuff yourself. If you delete a part on the Client that a server created, if you move that part into ServerStorage on the server, and then introduce it back into Workspace, it will be re-created on the Client as well.

This works like this just so that Server doesn’t have to keep track of the fact that that Client X deleted a part locally. I’m not saying this has to remain true, but unless this behavior somehow prohibits important gameplay scenarios, I doubt we will change our architecture to work any differently.

3 Likes

That’s probably how it should be.
Now the idea in my previous post about “removing from memory on :Destroy()” is very doable.

Has this fix been implemented?

Not yet. ROBLOX had to delay the release this week. It was too risky to flip the fix on Friday, so I will flip it early next week. (Possibly Monday night).

2 Likes

Just pushed it out. Confirmed that Repro Level no longer leaks. Monitoring to make sure this didn’t change anything unintended.

11 Likes