Destroyed ViewportFrames do not release themselves from memory

There’s an issue regarding ViewportFrames, where it doesn’t release itself from memory when Destroy() is called.

I discovered this issue while testing out the game “Guts & Blackpowder” with our new shop. Our shop deletes old ViewportFrames because we’d assume it would help optimize the game. But when I looked under the “Signals” Memory section on the client, it kept rising up and would plateau where it added the memory.

At first I thought I was crazy, but when I made a separate place with no parts, no spawning players, and the Lighting set to Compatibility, I’ve noticed the memory climbing. It became more noticable when I created 5 new ViewportFrames.

Attached to this post is the place I created for this specific test.
BugReportPlace.rbxl (47.2 KB)

10 Likes

We’ve filed a ticket into our internal database for this issue, and we will update you when we have further information!

Thanks for the report!

6 Likes

After setting the number of viewport frames per mouse click from 5 to 500, I noticed how it would start lagging over time and it would be slower and slower. I realized I had managed to get from about 1400 MB of memory usage to 2400 MB of memory usage. So, yeah, this can definitely cause problems.

But then I realized that the script itself has a memory leak unrelated to ViewportFrames: In my scenario, 500 frames were being added to an array per-click, and it turns out that the for-loop at the beginning on the .MouseButton1Click function was the reason that it was lagging: the array is never cleared and keeps references to all the ViewportFrames every created.

Just adding a little viewport_table = {} after the for-loop not just completely got rid of the lag over time, but also massively reduced how much memory was being leaked. There is a still another memory leak very much related to ViewportFrames after doing this, but it is far smaller. In my testing, with the array memory leak after exactly 203,000 viewports, my memory usage when from 1500 MB to 1873 MB, but after fixing that leak, at over 1 million viewports my memory usage was still at around 1635 MB.

So, not discrediting this bug report, it’s just that the repro file has it’s own memory leak that may serve as a red-herring.

3 Likes

That was definitely my mistake then. I forgot that clearing a table doesn’t clear the references in the array, only the objects. I should’ve just re-referenced the table after clearing.

But to my knowledge, the issue seems to be fixed (or mitigated significantly) now. Regardless, I’ll keep that issue in mind.

1 Like

Any updates on this? Still having this issue impact my game extensively. (It uses viewports to display avatar customization options)

Hi @sicknoobie - could you add some more details w/ a repro file that demonstrates the issue?

No actually, it turns out it was due to a different memory leak! If you make connections to UserInputService and the script that made the connections is destroyed, it sits in memory forever! That resulted in the script (along with several modulescripts it kept in memory due to referencing) remembering all of the viewport frames.

1 Like

Thanks for the information. We will investigate and follow up with updates when we can!

Thanks for the details! For this specific issue you mentioned, do you have an example in mind or a simple repro file? This might help us to identify a potentially memory leak on rcc that existed for a long time.

MemoryLeakFromInputServiceRepro.rbxl (64.5 KB)

Heres a simplified example of it!

To Reproduce Memory Leak:

  1. Hit the button to delete the gui a few times
  2. Open Luauheap and create a client snapshot
  3. In the unique references list, note that all instances of the gui are still there
  4. Open create a server snapshot
  5. In the unique references list of the server snapshot, note that only about 1 reference of the gui is there (due to the way its setup)

Example of “Fixed” Version:

  1. Using the proximity prompt, toggle it to switch to the FIXED version.
  2. hit the button to delete the gui a few times (note that only blue versions of the gui are fixed)
  3. Hit the button to delete the gui a few times
  4. Open Luauheap and create a client snapshot
  5. In the unique references list, note that all instances of the fixed gui are cleaned up, but the unfixed gui remains

Included here is a video of me showcasing it:

External Media
2 Likes

Would love to hear back @0xabcdef1234, if anything does arise from this!

Tested this and can vouch that this memory leak also occurs to me!

1 Like

Hi, we talked with internal teams and we think this one might relates to the PSA: Connections can memory leak Instances!, as the topic is far off from the original ticket, we will close this one out and submit it as a feature request of better garbage collecting logic. Thanks for your investigation and repro files :heart: it is pretty helpful.

1 Like

Circling back to this actually, according to the :Destroy() API documentation, the script should disconnect all its connections? Much like how if I had a script make a connection to say, a basepart’s color change, that connection gets cleared up and destroyed when the script is removed. Why do UserInputService connections not get disconnected when the script making them is destroyed?

API Reference: