Unity内存分析-Texture引用计数-如何让UI界面在Destroy时释放掉手动挂上去的静态资源(如背景图)
标签:
texture引用内存回收 |
分类: 修炼Unity |
写博客之前我们先来看三张图
图一:游戏刚运行时,在Hierarchy视图中可以看到,我还没有创建Cube1,所以此时Profiler中没有Texture2D的引用
图二:此时我点击了按钮“Create
Cube1”创建Cube1,在Hierachy视图中可以看到,并且上面挂了一个UISprite脚本,此时Profiler视图中,已经有了图集TextureAtlas的引用(引用数为7)
图三:点击“Destroy”按钮销毁Cube1,在Hierrachy视图中可以看到Cube1已经不存在了,
此时Profiler视图中,TextAtlas的引用仍然存在(引用数为1)!!!!
这里的TextAtlas图集占用内存比较小,只有170.8KB,但是如果占用8M呢,那么这8M就会在切换场景之前使用存在在内存里,如果玩家在主城中频繁点击页面,又会有其他图集的引用,这样很快,内存就不够用了,低端机尤为明显
通过Profiler我们可以分析出TextAtlas是被Material引用着。是不是能有启发呢?
在UI页面显示时,我们可以收集该页面及其所有子节点的Material,如下我写了一个PanelResources的脚本,其中的MMats(List)收集的就是PAw_Award下的所有material.
这样在页面销毁时,我们就会便利MMats(List)
for(int i = 0; i < MMats.Length; i ++)
{
}
此时我们再看Profiler监测,TextAtlas引用计数是不是为0了,这个时候在上面的这个循环后边加两行代码:
Resources.UnloadUnusedAssets();
System.GC.Collect(); 才能实现真正的内存回收(就是又会出现图一情况了)
注意,注意,这个时候还没有结束,我们再次点击"Create
Cube1"按钮,你会发现虽然Cube1创建出来,但是没有背景图了,查看TextAtlas,确实没了,这是因为
for(int i = 0; i < MMats.Length; i ++)
{
}
将贴图给置空了,你也许会很疑惑,我先在重新创建了一个Cube1,对应的材质引用啥的,应该是新的,应该有Texture才对,为啥没了??
这是因为Texture是个引用而不是复制,所以你在循环中置空,会直接影响到原图
这时候你在Project视图中查看确实如此。
这又怎么解决呢?
在页面显示时,我们收集了Material到MMats中,Material的贴图通过代码赋值上去,岂不就解决了
此外:我们可以把收集Material代码在编辑模式下完成。
总结:
1. 编辑模式下:收集Material至MMats
2. 创建页面时,
for(int i = 0; i < MMats.Length; i ++)
{
}
2. Destory页面时,
for(int i = 0; i < MMats.Length; i ++)
{
}
Resources.UnloadUnusedAssets();
System.GC.Collect();

加载中…