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.
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.
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.
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.
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.
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 it is pretty helpful.
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?