原创文章如需转载请注明:转载自风宇冲Unity3D教程学院

                       
                       U3D内存优化
 
读了Hog关于内存管理文章, 自己测试了下。
有以下收获:
(1)Unity的Profiler性能监测是非常准确。
(2)测试复盘的 结果也完全与Hog的一致
 
(3)但是场景里已经放的物体,删除后,GameObject,Transform等复制出来的是被删掉了.但是引用的贴图却没有被删除。使用Resources.UnloadUnusedAssets并没有效果. 
或者实时创建的,依然没有被释放。
 
最后用了Resources.UnloadAsset(t2d);才得到释放。
(4)Resources.UnloadUnusedAssets(); 释放的资源并不一定是 Resources文件夹下的,内存里有的都算。
 
(5)有人说删除总是会被延迟到当前帧的末尾:所以需要这样
  1. IEnumeratorOnLevelWasLoaded(int level)
  2. {
  3. Destroy(gameObject);
  4. yield return null;
  5. Resources.UnloadUnusedAssets();
  6. }
 
但实测发现上并不如此,无论是Destroy(obj); 还是DestroyImmediate(obj); 之后立刻调用Resources.UnloadUnusedAssets();都会被释放。
 
(6)删除

DestroyImmediate(obj);

t2d = null;

mat=null;

Resources.UnloadUnusedAssets(); 
 
t2d是reference到UIAtlas这张贴图,属于direct reference。 而mat这个材质上的mainTexture是reference到UIAtlas,所以mat是indirect reference。 而不管是direct reference 还是indirect reference都必须为null,即t2d及mat都必须为null, 否则UnloadUnusedAssets就不起作用。
 
所以在Inspector里指定的,有reference,一运行就会自动加载该资源。
 
(7)Resources.UnloadAsset(t2d);
当使用Resources.UnloadAsset后,若依然有物体用该图,那么物体就变全黑
 
(8)
 
可以Destroy引用
 
  1. using UnityEngine;
  2. using System.Collections;
  3. public class MyTest : MonoBehaviour {
  4. private GameObject obj;
  5. void OnGUI()
  6. {
  7. if(GUI.Button(new Rect(0,0,100,50),"Create"))
  8. {
  9. GameObject tmpPrefab =  Resources.Load("myTestPlayer") as GameObject;
  10. obj = Instantiate(tmpPrefab) as GameObject;
  11. Instantiate(tmpPrefab);
  12. }
  13. if(GUI.Button(new Rect(0,50,100,50),"Delete"))
  14. {
  15. Destroy(obj);
  16. Resources.UnloadUnusedAssets();
  17. }
  18. }
  19. }

也可以自己删自己

  1. using UnityEngine;
  2. using System.Collections;
  3. public class DeleteSelf : MonoBehaviour {
  4. void Start () {
  5. Destroy(gameObject,3f);
  6. }
  7. }

不光是开始的时候,任何时候加载 物体,里面有引用的话。都会载入都内存里。

结论
资源加载分为静态加载和动态加载,
静态加载: 场景中静态物体加载
动态加载: 
(1)public GameObject指向prefab,
(2)Resources.Load, 
(3)Assetbundle
其中(1)(2)都是在Instantiate的时候才加载贴图等资源,所以容易在创建物体时有卡顿现象,解决办法是预先Instantiate然后隐藏。(3)是在Assetbundle.Load的时候就加载贴图等资源了,Instantiate时仅仅时clone,所以不会在创建物体时出现卡顿现象。
 
不建议使用public GameObject指向prefab。小型游戏可以直接使用Resources.Load然后预创建的方式。大型游戏特别是网游建议全部用Assetbundle。但是Assetbundle是不适合快速迭代开发的。个人觉得可行的思路是先快速迭代开发原型,等原型及核心玩法接受实际去玩的验证并通过后,再使用Assetbundle并采用 模块->拼接的方法进行开发。
 
Application.LoadLevel是会自动释放上一个场景所占用的内存的,包括动态创建的物体(但是不包括AssetBundle文件自身的内存镜像,那个必须要用Unload来释放,用.net的术语,这种数据缓存是非托管的。)。因此短时间的场景或者 场景里内存在初进场景后增加幅度不大的时候,都可以采用场景切换来自动释放内存的。而面对在一个场景里,内存有增加,或者说不断增加各种物体的话。那么就需要Resources.UnloadUnusedAssets。ab的话,则是AssetBundle.Unload
AssetBundle.Unload(flase)是释放AssetBundle文件本身的内存镜像,不包含Load创建的Asset内存对象。
AssetBundle.Unload(true)是释放那个AssetBundle文件内存镜像和并销毁所有用Load创建的Asset内存对象。
 
Reference:

最新文章

  1. Demo源码放送:打通B/S与C/S !让HTML5 WebSocket与.NET Socket公用同一个服务端!
  2. UVA 11404 Palindromic Subsequence[DP LCS 打印]
  3. Liferay 6.2 改造系列之五:修改默认站点的页面内容
  4. Sublime Text 设置文件详解
  5. 160826、浏览器渲染页面过程描述,DOM编程技巧以及重排和重绘
  6. web设计经验<二>设计华丽的用户体验的6个热门技巧
  7. javascript异步执行函数导致的变量变化问题解决思路
  8. [BZOJ 3791] 作业 【DP】
  9. [原创]旧事重提:只配置参数实现OAuth2登录
  10. PoolManager 简单使用
  11. 获取MySql每一列的数据类型和长度默认值等信息
  12. Mysql 测试题
  13. sybase central 报 NullPointerException 解决
  14. struts2框架之自定义拦截器和配置
  15. bitcoin PoW原理及区块创建过程
  16. python笔记26-命令行传参sys.argv实际运用
  17. Python3 re模块正则表达式中的re.S
  18. 常用EL函数汇总 fn:contains ,fn:substring,fn:substringAfter...
  19. react 设置代理(proxy) 实现跨域请求
  20. 补习知识:Entity Framework Code First属性映射约定

热门文章

  1. js自动检索输入文章长度
  2. MYSQL-----IFNULL()函数的用法
  3. GO基本数据结构练习:数组,切片,映射
  4. jquery 获取某a标签的href地址 实现页面加载时跳转
  5. Hadoop(八)Hadoop数据压缩与企业级优化
  6. Visual Studio 中如何同时注释多行和取消注释多行
  7. 四 Python基础
  8. jquery放大镜非常漂亮噢
  9. Ubuntu 18.04 更改静态IP
  10. linux网络管理----网络基础