Memory Leak from Destroyed Objects/Models

Hello all,

Recently, my game’s servers have been crashing due to the server hitting the 6.25 GB limit in server memory. I was concerned there may have been a possible memory leak with this, so I decided to test things into my own hands. When viewing active servers’ memory, I realized that (as usual) server memory increases when players spawn cars. I wasn’t exactly concerned with this itself, but what does concern me is the fact that the server memory does not go down when the car is destroyed. This seems like a ROBLOX internal issue, but if it isn’t (and it’s a me issue), I’d love to hear any feedback.

And yes, I understand the server memory is pretty large even on server startup, but one of the goals for the game is make an immersive, realistic map, so unfortunately there isn’t any way around it (if you have tips let me know though!)

Here is a Google Sheet of my findings:

“Normal” column is when the server is first started up, and the rest of the columns are self-explanatory.

Here is a video demonstration of this issue:

As you can see, I spawn in 128 cars and destroy them. One can expect the memory to decrease back to normal when they are destroyed, but that is not the case.

I understand that spawning 128 cars all at once may not be the best test (considering the servers are max at 30 players), but it does simulate what can happen over time during a server’s lifespan.

Let me know if you have any thoughts on this and any workarounds in the mean time.

EDIT:
Here is a place file where you can test this for yourself!
MemLeak.rbxl (5.7 MB)

23 Likes

If there are any scripts that refer to those cars, they will not be garbage collected, since the collector has no way of knowing if you are going bring them back later. You can usually fix this by making sure to use Destroy() when removing objects.

1 Like

Dm @bug-support and they’ll make your dm a bug report

1 Like

Instances will only be garbage collected if there are zero references to them in your code.

This means that if there are variables or tables that store references to your cars and their components, calling Destroy on them will not actually remove them from memory. You must set those variables and references in tables to nil before the cars can be garbage collected.

1 Like

You’re sure this isn’t your code’s fault right? If you could provide your code, please do so we can look at what might cause this.

1 Like

The only references made to the car are functions that get called when players do certain things. However, in the video, I just spawn and destroy them, so there couldn’t be anything else in which car is referenced apart from the car spawner and the scripts within the car (which get destroyed since I destroy the car). I already set the car variable to nil in the spawn script, but it didn’t have an effect to the memory.

Tagging you too since I saw your reply. @Content_Corrupted019

1 Like

View the reply I just sent above, should help. I would have mentioned you but I didn’t see you reply until after.

1 Like

I would go ahead and file a bug report @Bug-Support.

1 Like

Yeah I sent them the link to this for them to transfer over. I appreciate it!

1 Like

Here’s a video:

As you can see in the video towards the end, I set the Car (the car model) and Result (boolean) variables to nil after spawning them with the module. The module function returns the Car model and a boolean that indicates success in a tuple.

Even when setting the variables to nil, the memory does not go down. I do not have anymore references to the car model elsewhere apart from other actions players can do, but I don’t do them in the video.

@Content_Corrupted019

1 Like

Can you send a repro place file with the spawn and destroy code?

It’s also important to keep in mind (at least from my experience) garbage collection doesn’t always happen right away, so it’s possible they were getting garbage collected, it just took some time.

1 Like

Sure thing, here’s a testing plate I made. It seems to work in here as well. Just spawn however many cars you want, and press the red part to delete them. You can view the server script in ServerScriptService.

I didn’t use the exact car models as my game since I want to respect the developer that made the car models shown in the video. However, I put in a similar car model that uses the same chassis system.

MemLeak.rbxl (5.7 MB)

1 Like

Are you sure that there is no self-referential connections? This is the first thing that comes to mind when destroying objects doesn’t allow every aspect of them to be fully garbage collected.
Read more here.

The only connections are within the scripts parented in the car itself. However, shouldn’t the connections be destroyed when the car is destroyed? You can test it out with the baseplate I sent in a reply above. The scripts within the car reference parts of the car and sometimes the car model itself. However, when the car is destroyed, they (the scripts and its connections) should be destroyed too right?

Afaik this only happens for the ‘obvious’ connections. Like a player added event connection at the top level of your script.

Indirect connections made through modulescripts aren’t necessarily cleaned up I think. Especially if these modulescripts don’t get destroyed.

I suggest disabling scripts until the memory leak disappears. Then slowly re-enabling them. It’s the best way we have to debug memory leaks… (unfortunately)

I don’t think that’s the issue, at least entirely. Try out the place file I sent in a reply above. The memory is still there after the cars are destroyed. I don’t have any other scripts that connect to car models, in both the test place and the main game. The memory seems to go up a lot with these cars.

What I understand what you’re asking is that the connections should be disconnected when the car is destroyed. Generally yes. The only edge-case I’m aware of that they won’t disconnected when is when you have self-referential connections, for example:

SOMETHING123.Changed:Connect(function()
    if SOMETHING123 then --this is the mistake, referencing SOMETHING123 inside a connection to SOMETHING123
       --code
    end
end)

You can check the link I posted earlier for more specific information and context. Unfortunately I don’t have access to studio at the moment so I can’t check out your baseplate place.

Ohhh alright. I see what you’re saying now I misunderstood your other reply. So basically, any connection function that references the object where the event is, would make the instance not GC?

Not necessarily. I’m not 100% certain about whether it affects the instance, but moreover the connections themselves. Connections can become very expensive very quickly as they accumulate. Beware that this is only one of many possible reasons for your memory leak. As I said above, please read this topic as it does a much better job of explaining this than I do.

1 Like

I just read it. Pretty good read honestly, thanks for sending it.
I removed all the scripts within the vehicle just to test it wasn’t a script-related issue. The memory still persists after deletion. In the video below, you can see I remove all the scripts (local, server, module) from the vehicle, and then spawn them, before running the studio. After deletion of the vehicles, memory did not go down entirely.

However, I did notice that after like 10 seconds (from a previous test) the memory did go down a little bit compared to the memory right after deletion, so based on that I believe it did GC, but not entirely