CUI usage leads to memory leak on client

Hi, everyone

 

I've faced an issue that is reproducible on my and two other machines. If we use any plugin that sends CUIs to clients, that causes memory leaks.

I'm wondering if it's a known issue.

As an example I've written tiny plugin to reproduce the issue:

using System.Collections.Generic;
using UnityEngine;
using System;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Plugins;
using Newtonsoft.Json;
using Oxide.Core;

namespace Oxide.Plugins {
    [Info("Test Cui Leak", "Egor Blagov", "1.0.0")]
    [Description("Plugin to test memory leaks on CUI")]
    class TestCuiLeak : RustPlugin {
        [PluginReference]
        private Plugin ImageLibrary;
        private HashSet<ulong> playersWithCuis = new HashSet<ulong>();
        private const string testImage = "https://rust-wiki.com/images/thumb/6/67/Recycler.png/300px-Recycler.png";
        private const string panelName = "testcuileak.main-panel";
        private const int imageCount = 100;

        private void OnServerInitialized() {
            if (!ImageLibrary.Call<bool>("HasImage", testImage)) {
                ImageLibrary.Call("AddImage", testImage, testImage, 0UL);
            }
        }
        private void Unload() {
            foreach (var id in playersWithCuis) {
                BasePlayer player = BasePlayer.activePlayerList.Find(x => x.userID == id);
                CuiHelper.DestroyUi(player, panelName);
                for (int i = 0; i < imageCount; i++) {
                    CuiHelper.DestroyUi(player, $"{panelName}.{i}");
                }
            }
        }

        [ChatCommand("testleak")]
        private void TestCmd(BasePlayer player, string cmd, string[] argv) {
            if (!playersWithCuis.Contains(player.userID)) {
                var elements = new List<CuiElement>();

                var panel = new CuiElement {
                    Parent = "Hud",
                    Name = panelName
                };

                panel.Components.Add(new CuiImageComponent {
                    Color = "0.1 0.1 0.1 0.8",
                });

                panel.Components.Add(new CuiRectTransformComponent {
                    AnchorMax = "0.5 0.5",
                    AnchorMin = "0.5 0.5",
                    OffsetMin = "-200 -200",
                    OffsetMax = "200 200"
                });
                elements.Add(panel);

                for (int i=0; i< imageCount ; i++ ) {
                    var image = new CuiElement {
                        Parent = panelName,
                        Name = $"{panelName}.{i}"
                    };
                    image.Components.Add(new CuiRawImageComponent {
                        Png = ImageLibrary.Call<string>("GetImage", testImage)
                    });
                    image.Components.Add(new CuiRectTransformComponent {
                        AnchorMax = "0.7 0.7",
                        AnchorMin = "0.3 0.3"
                    });
                    elements.Add(image);
                }
                CuiHelper.AddUi(player, elements);
                playersWithCuis.Add(player.userID);
            } else {
                CuiHelper.DestroyUi(player, panelName);
                if (argv.Length == 1) {
                    for (int i = 0; i < imageCount; i++) {
                        CuiHelper.DestroyUi(player, $"{panelName}.{i}");
                    }
                }
                playersWithCuis.Remove(player.userID);
            }
        }
    }
}

input.bind keypad1 chat.say /testleak

input.bind keypad2 chat.say "/testleak all"

 

if you spam either keypad1 or keypad2 you will find out that every time the cui appears, about 50Mb of RAM are leaked.

/testleak -- shows and removes CUI (removing only parent)

/testleak <any_arg> -- shows and removes CUI (removing all CUIs)

 

Please let me know if this issue is well known, and maybe there is any workaround? Or something that could be done on a client to free the memory. (gc.collect doesn't help).

 

Only reconnect to the server resolves the problem.

 

Thanks & regards,

Egor.

The CUI that Rust provided isn’t exactly resource friendly.
In response to Wulf ():
The CUI that Rust provided isn’t exactly resource friendly.
Are we able to ping dev command, or they are not interested in fixing this issue? I guess if I post a bug report they will just ignore it...

Did you find a solution to this?