WzComparerR2 icon indicating copy to clipboard operation
WzComparerR2 copied to clipboard

关闭 MapRender 后内存不会被清理

Open HikariCalyx opened this issue 1 year ago • 1 comments

之前在测试 ARM64 版 WzComparerR2 时发现,打开 MapRender 后再关闭,已占用的内存不会被自动清理。 随后发现 x86 / x64 版本的 WzComparerR2 上也可复现此情况。

以我自己的环境为例:

  1. 打开 WcR2_With_Plugins_20250116.1 的 WzComparerR2.anycpu.exe,初始内存占用稳定在 83,880 KB。
  2. 加载 CMS v213 客户端的 WZ 文件后,内存占用来到了 432,152KB。
  3. 使用 MapRender 随意加载一张地图,例如 100000000。此时内存占用来到了 941,800KB。
  4. 关闭 MapRender 后,内存占用没有下降。关闭 WZ 文件后内存占用仅降低至 688,940KB。

可能原因是 MapRender 关闭时没有进行 GC.Collect。

HikariCalyx avatar Jan 23 '25 14:01 HikariCalyx

尝试做了一些性能分析,发现了几个内存泄漏点:

  1. UI框架内存泄漏,在AdvTree清空节点以后,node和cell会因为一些私有字段持有被删除的节点的引用,导致无法被GC回收。
  2. 随着MapRender2读取地图,会有大量img被解压读取导致内存占用提高。
  3. MapRender2中,如果在刚刚进入或退出地图的时候关闭窗口,控制bgm音量的Task会一直处于active状态导致无法回收。
  4. Monogame内部的VertexDeclaration有静态缓存,会导致GraphicsDevice被引用导致无法回收。
  5. MainForm上的GraphicsControl在清空绘图资源后,已加载的Texture2D不会自动释放导致内存泄漏。

如上很多问题都不是调用GC.Collect强制回收可以解决的,目前对64位运行时下的内存占用也确实没有太好的优化手段。后面等到issue列表主要的bug修理完后可以考虑做做内存优化,但也不要抱太大期望。

Kagamia avatar Feb 02 '25 06:02 Kagamia