Introducing the Luau VM memory exploration tools

I’m having this same issue in my game Empire Clash - the server just wont work. Creating a snapshot will cause the server to hang for a few seconds. However, no snapshot will generate after the hanging stops.

Please try again to see if you are still not getting a report.

Still not working for me

I managed to somewhat dial down the issue where I figured out where after x code is ran and all code after it, then the issue starts to occur

Hi
Seems to be working for servers with 2GB or so server memory.
Getting a ‘failed to send data’ server crash if the server has 4-5GB of memory.

This tool has brought attention to me an issue of what I would call “reference looping”?

For some reason this setup (or similar setups) hang out in nil FOREVER despite everything being :Destroy()ed


I’m not super technically-informed with LuaU so I’m not entirely sure on what these references mean and/or how I would fix something like this, but it’s something!

ReferenceLoop.rbxl (54.3 KB)

For added context, a few GUIs in my game have modules located in them for organization purposes, which are causing this issue and resulting in a memory leak for the game. Hoping to get it all sorted out soon!

Unfortunately, engine often cannot clear the result table of a module, even if if the ModuleScript is destroyed.
We checked and there were multiple games that relied on calling require on a destroyed ModuleScript.

Some developers asked us to not change this behavior: Release Notes for 596 - #15 by ceat_ceat

As a workaround, before destroying a ModuleScript, clear its result table manually:

table.clear(require(Setup.GoofyModule))
Setup:Destroy()

Would you ever consider adding this as a setting we could change in the future?

@Malt_WasHere , @ShoomamaAtlantis please check one more time, you should be getting your server heap captures.

works now, thanks. seems to operate as normal now

the one thing i’m observing is apparently explosions w/ explosion.Hit connections are never cleaned up after the explosion has finished? I was trying to trace an ever expanding memory footprint on some relatively straightforward scripts and believe I narrowed it to a simple explosion instantiation w/ explosion.Hit:Connect(…

What’s the proper way to fully clean up an explosion.Hit connection after it has run it’s course? I’m surprised to learn this doesn’t appear to be done automatically.

Edit: I tried just slapping a
task.delay(3,function() explosion:Destroy() end)
in after the explosion was parented to the workspace and it stopped the runaway memory allocation… Wild as this isn’t mentioned anywhere in roblox docs nor do any of the guides on adding explosions mention the need to manually cleanup. My game uses a lot of em too :o

It is now possible to click on ‘…’ and see all items inside. (Roblox version 614)

1 Like

Why does unique references show up on things that are already destroyed & set to nil from all tables:


I modified this module to make sure that the tables that contain the parts gets set to nil once it is destroyed, this also happens on other things like the player instance and the character instance even tho no table is holding a reference to them and i understand there are other things like connections and such but even connections should be automatically destroyed if the object has been destroyed, this is importantly concerning, is it possible that unique references doesn’t show all paths possible and only some or is there some explanation?

1 Like


How could I fix this? I’m not sure how else I can improve on this? (Ignore the typechecking whoops)

1 Like

You can take the connection returned by Connect and use that object to disconnect in PlayerRemoving signal.

Alternatively, if this on the server, you can try auto-destroy of Player and Character using this property: New Player and Character Destroy Behavior
(if it doesn’t break something in the experience)

One other option is to not capture outer variables like ‘Player’ argument from inside the connection, but this is not always possible.

1 Like

What about this? Sorry for the questions, I’m a bit new to utilizing this tool.

image

Here is the character added event for the module:

In the first code snippet, ‘stack’ refers to the arguments and locals of the function (Player, Character, Clone)

The most likely reason for these references to be active is that the read is forever stuck in the task.wait loop because LoadedData never became true.

1 Like

I’m a bit confused on the difference between self and stack, is anyone able to provide an example with a definition?

At the moment, I’m working on lowering my array count as I have, “popUpTextBuffer” at 10981 size and 128 self (I assume these are in bytes) which is a descendant of “array” which has a size of 1101126 and self value of 868112.

What unit is “Size” exactly? I figured it was bytes but global being 8 MB seems a bit too low, unless it isn’t of course.

1 Like

The size is counted in ‘bytes’.
‘global’ is for things that were not assigned a category, like VM support data structures, including the registry table.

2 Likes

It would be cool if the developer console works as a code editor like in studio.