unity 2021.3 UGUI内存泄露IndexedSet未释放

起因:用Unity2021.3.15f1打的项目在外网发现托管堆无限增长

一.排查原因
通过MemoryProfiler排查发现是Graphic对象泄露

排查Unity 2021.3.15f1的UGUI逻辑,发现是graphic节点移动之后,canvas释放不正确。
原因是2021.3.15f1 UGUI对IndexedSet和CanvasRegister两个类做了缓存优化。

具体原因如下:
1.Unity 2020 UGUI graphic移动父节点Canvas流程


graphic节点移除之后会直接remove

2.Unity 2021 UGUI graphic移动父节点Canvas流程


graphic节点移除会把graphic移到队列最后,并不会直接移除

二.构建Demo测试用例

测试代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Profiling;
using System;

public class MemoryTest : MonoBehaviour
{
    public GameObject canvas1;//canvas1节点
    public GameObject __canvas2; //canvas2 原型
    public GameObject __graphic; //子节点graphic 原型,里面加了很多Text对象增加内存泄露直观表现
    public Text text; //显示内存信息
    // Start is called before the first frame update
    IEnumerator Start()
    {
        
        while (true)
        {
            //创建canvas2
            var canvas2 = GameObject.Instantiate(__canvas2);
            //在canvas2节点下创建graphic
            var graphic = GameObject.Instantiate(__graphic,canvas2.transform);
            yield return new WaitForSeconds(0.2f);
            //image1节点移动到canvas1
            graphic.transform.SetParent( canvas1.transform);
            //销毁canvas2和graphic
            Destroy(canvas2);
            Destroy(graphic);
            yield return new WaitForSeconds(0.1f);

            //显示托管堆内存
            text.text ="Mono Used Size:"+ Math.Round(Profiler.GetMonoUsedSizeLong()*0.00000095367431f,2)+" MB";

            //调用内存释放GC
            System.GC.Collect();
            Resources.UnloadUnusedAssets();
        }
    }

}

测试场景:

运行结果:


内存随着时间不断增加

三.修复UGUI
根据排查原因,修复UGUI
1.修改UGUI源码





修改其中CanvasRegister代码

2.运行Demo测试



内存不再上升,修复成功。

四.总结

这个UGUI内存泄露bug过于离谱,目前只检查了unity2021.3.15f1和unity2021.3.8f1有问题,2020暂时没发现。
如果是我判断错误希望知情人士讲解一下。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值