原创文章如需转载请注明:转载自风宇冲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:

U3D内存优化的更多相关文章

  1. U3D DrawCall优化手记

    在最近,使用U3D开发的游戏核心部分功能即将完成,中间由于各种历史原因,导致项目存在比较大的问题,这些问题在最后,恐怕只能通过一次彻底的重构来解决 现在的游戏跑起来会有接近130-170个左右的Dra ...

  2. 【转】 U3D DrawCall优化手记 - 夜阑卧听风吹雨

     原文  http://www.cnblogs.com/ybgame/p/3588795.html 在最近,使用U3D开发的游戏核心部分功能即将完成,中间由于各种历史原因,导致项目存在比较大的问题,这 ...

  3. (转)U3D DrawCall优化手记

    自:http://www.cnblogs.com/ybgame/p/3588795.html 在最近,使用U3D开发的游戏核心部分功能即将完成,中间由于各种历史原因,导致项目存在比较大的问题,这些问题 ...

  4. In-Memory:内存优化表的事务处理

    内存优化表(Memory-Optimized Table,简称MOT)使用乐观策略(optimistic approach)实现事务的并发控制,在读取MOT时,使用多行版本化(Multi-Row ve ...

  5. 试试SQLSERVER2014的内存优化表

    试试SQLSERVER2014的内存优化表 SQL Server 2014中的内存引擎(代号为Hekaton)将OLTP提升到了新的高度. 现在,存储引擎已整合进当前的数据库管理系统,而使用先进内存技 ...

  6. In-Memory:内存优化表 DMV

    在内存优化表的DMV中,有两个对象ID(Object ID): xtp_object_id 是内部的内存优化表(Internal Memory-Optimized Table)的ID,在对象的整个生命 ...

  7. android内存优化

    背景 虽然android设备的配置越来越高,但是,由于android系统的机制导致(最主要是app程序的主线程不会真正退出而是在后台常驻内存中) ,这样手机中安装过多的app之后,导致内存被大量占用, ...

  8. JavaScript内存优化

    JavaScript内存优化 相对C/C++ 而言,我们所用的JavaScript 在内存这一方面的处理已经让我们在开发中更注重业务逻辑的编写.但是随着业务的不断复杂化,单页面应用.移动HTML5 应 ...

  9. [WP8.1UI控件编程]Windows Phone大数据量网络图片列表的异步加载和内存优化

    11.2.4 大数据量网络图片列表的异步加载和内存优化 虚拟化技术可以让Windows Phone上的大数据量列表不必担心会一次性加载所有的数据,保证了UI的流程性.对于虚拟化的技术,我们不仅仅只是依 ...

随机推荐

  1. Linux 硬盘挂载方法

    linux 硬盘分区,分区,删除分区,格式化,挂载,卸载笔记 硬盘挂载操作工作步骤: 1.先查看目前机器上有几块硬盘,查看命令有两种: 命令1:# fdisk –l 命令2:# dmesg | gre ...

  2. 编译报错:LC.exe 已退出

     

  3. 三十分钟理解计算图上的微积分:Backpropagation,反向微分

    神经网络的训练算法,目前基本上是以Backpropagation (BP) 反向传播为主(加上一些变化),NN的训练是在1986年被提出,但实际上,BP 已经在不同领域中被重复发明了数十次了(参见 G ...

  4. Effective STL 笔记: Item 6--Be alert for C++'s most vexing parse

    假设有个文件里面记录的一系列的 int 值,现在我们想把这些数值存到一个 List 里面,结合 Item 5, 我们可能会写出下面的代码: ifstream dataFile("ints.d ...

  5. 使用Python快速查询所有指定匹配KEY的办法

    import redis redis_ip = '10.10.14.224' redis_port = 18890 # 配置redis的连接办法 # http://blog.csdn.net/u010 ...

  6. Codeforces Round #492 (Div. 2) [Thanks, uDebug!]

    这次的题好奇怪哦... C - Tesla 思路:先把跟停车位相邻的车停进去,然后开始转圈... #include<bits/stdc++.h> #define LL long long ...

  7. Cordova - 禁用整个应用页面的上下拖动效果(防止拖动出现黑边)

    可在 config.xml 中进行如下设置:   <preference name="WebViewBounce" value="false" /> ...

  8. thinkphp5.0配置加载

    ThinkPHP支持多种格式的配置格式,但最终都是解析为PHP数组的方式. PHP数组定义 返回PHP数组的方式是默认的配置定义格式,例如: //项目配置文件 return [ // 默认模块名 'd ...

  9. 关于 Unity 项目中的 Mono 堆内存泄露

    关于 Unity 项目中的 Mono 堆内存泄露 题记:这是补一篇应该在将近一年前就应该写的记录,今天终于补上. 内存泄露是一个老话题了,之前我专门写过一篇 排查 Lua 虚拟机内存泄露 的文章,并且 ...

  10. Java常用工具类之时间转换(注释乱码,全)

    package com.wazn.learn.util; import java.text.ParseException; import java.text.SimpleDateFormat; imp ...