• profiler内存优化:警惕回调函数


      最近做profiler内存优化,踩了一个深坑,觉得有必要做一下笔记。
    过程是这样的,游戏启动后,会启动更新模块,加载更新界面,更新检测完成后会切换场景进入登陆界面。切换场景会自动释放上一个场景的资源。
    但是问题来了,切换场景后,更新界面关闭了,但是更新界面引用的atlas、font之类的asset资源(这些资源仅使用在更新界面),没有自动释放,还存在内存中。
    如下图的动态字库,占了18MB内存, Update就是atlas材质球引用的贴图,占了2MB内存。
     
    反复的检查了代码,没有设置DontDestroyOnLoad,没有静态引用任何资源,更新窗体脚本的OnDestroy也是调用了的,百思不得解。
    最后不得不用最笨的办法,一段一段代码注释掉,看是否哪块代码出了问题。首先从Awake开始,直接做切换场景,然后看profiler
     
    Update贴图已经不在了,有戏。然后放开Awake,继续,最后终于查到一段代码
    这里DownDllCallback最后回调函数传递给一个子线程,因为回调函数是一个成员函数,传递参数会把当前类的this指针给传进去,导致其他地方
    对这个类有引用,切换场景自然就不能自动释放了。搞了半天,原来是回调函数惹的祸。
     
    解决办法有两个:
    1. 将回调函数设置成静态函数,这样就不带this指针了
    2. 在适当的地方,将回调函数卸载掉,也就是事件注册和反注册,必须成对呀
     
    总结:
    1. 在MonoBehaviour脚本中,回调函数的使用也要注意,一不注意就导致脚本有多余引用,还不容易发现
    2. 要保持良好的代码习惯,通常注册了函数,使用完后没有对函数进行反注册,这个要时刻警惕,出问题真不好查。
  • 相关阅读:
    1、接口测试全流程
    7、执行 suite 后,result.html 测试报告中,测试结果全部显示为通过原因分析
    6、Python 中 利用 openpyxl 读 写 excel 操作
    5、Python 基础类型 -- Dictionary 字典类型
    4、Python 基础类型 -- Tuple 元祖类型
    cp: omitting directory”错误的解释和解决办法
    c++ 之bind使用
    Linux查找–find命令
    lsof命令总结
    Linux查看端口、进程情况及kill进程
  • 原文地址:https://www.cnblogs.com/fishyu/p/6879816.html
Copyright © 2020-2023  润新知