zoukankan      html  css  js  c++  java
  • profiler内存优化:警惕回调函数

      最近做profiler内存优化,踩了一个深坑,觉得有必要做一下笔记。
    过程是这样的,游戏启动后,会启动更新模块,加载更新界面,更新检测完成后会切换场景进入登陆界面。切换场景会自动释放上一个场景的资源。
    但是问题来了,切换场景后,更新界面关闭了,但是更新界面引用的atlas、font之类的asset资源(这些资源仅使用在更新界面),没有自动释放,还存在内存中。
    如下图的动态字库,占了18MB内存, Update就是atlas材质球引用的贴图,占了2MB内存。
     
    反复的检查了代码,没有设置DontDestroyOnLoad,没有静态引用任何资源,更新窗体脚本的OnDestroy也是调用了的,百思不得解。
    最后不得不用最笨的办法,一段一段代码注释掉,看是否哪块代码出了问题。首先从Awake开始,直接做切换场景,然后看profiler
     
    Update贴图已经不在了,有戏。然后放开Awake,继续,最后终于查到一段代码
    这里DownDllCallback最后回调函数传递给一个子线程,因为回调函数是一个成员函数,传递参数会把当前类的this指针给传进去,导致其他地方
    对这个类有引用,切换场景自然就不能自动释放了。搞了半天,原来是回调函数惹的祸。
     
    解决办法有两个:
    1. 将回调函数设置成静态函数,这样就不带this指针了
    2. 在适当的地方,将回调函数卸载掉,也就是事件注册和反注册,必须成对呀
     
    总结:
    1. 在MonoBehaviour脚本中,回调函数的使用也要注意,一不注意就导致脚本有多余引用,还不容易发现
    2. 要保持良好的代码习惯,通常注册了函数,使用完后没有对函数进行反注册,这个要时刻警惕,出问题真不好查。
  • 相关阅读:
    CF 848C
    BZOJ 4025 二分图
    支配树学习笔记
    CF1120D Power Tree
    Codeforces 360A(找性质)
    Codeforces 142D(博弈)
    Codeforces 142B(二分染色、搜索)
    GYM 101981E(开关反转性质)
    Codeforces 1150E(树、线段树)
    Codeforces 1150D(字符串dp)
  • 原文地址:https://www.cnblogs.com/fishyu/p/6879816.html
Copyright © 2011-2022 走看看