WzComparerR2
WzComparerR2 copied to clipboard
关闭 MapRender 后内存不会被清理
之前在测试 ARM64 版 WzComparerR2 时发现,打开 MapRender 后再关闭,已占用的内存不会被自动清理。 随后发现 x86 / x64 版本的 WzComparerR2 上也可复现此情况。
以我自己的环境为例:
- 打开 WcR2_With_Plugins_20250116.1 的 WzComparerR2.anycpu.exe,初始内存占用稳定在 83,880 KB。
- 加载 CMS v213 客户端的 WZ 文件后,内存占用来到了 432,152KB。
- 使用 MapRender 随意加载一张地图,例如 100000000。此时内存占用来到了 941,800KB。
- 关闭 MapRender 后,内存占用没有下降。关闭 WZ 文件后内存占用仅降低至 688,940KB。
可能原因是 MapRender 关闭时没有进行 GC.Collect。
尝试做了一些性能分析,发现了几个内存泄漏点:
- UI框架内存泄漏,在AdvTree清空节点以后,node和cell会因为一些私有字段持有被删除的节点的引用,导致无法被GC回收。
- 随着MapRender2读取地图,会有大量img被解压读取导致内存占用提高。
- MapRender2中,如果在刚刚进入或退出地图的时候关闭窗口,控制bgm音量的Task会一直处于active状态导致无法回收。
- Monogame内部的VertexDeclaration有静态缓存,会导致GraphicsDevice被引用导致无法回收。
- MainForm上的GraphicsControl在清空绘图资源后,已加载的Texture2D不会自动释放导致内存泄漏。
如上很多问题都不是调用GC.Collect强制回收可以解决的,目前对64位运行时下的内存占用也确实没有太好的优化手段。后面等到issue列表主要的bug修理完后可以考虑做做内存优化,但也不要抱太大期望。