Unity在场景切换之间清理下内存
2015-10-29 15:43
507 查看
看了两篇关于Unity加载和内存管理的文章,写得很详细。
文章链接:
http://game.ceeger.com/forum/read.php?tid=4394
http://game.ceeger.com/forum/read.php?tid=4466
Unity系统在加载新场景时,所有的内存对象都会被自动销毁,包括你用AssetBundle.Load加载的对象和Instaniate克隆的。
但是不包括AssetBundle文件自身的内存镜像,那个必须要用Unload来释放,用.net的术语,这种数据缓存是非托管的。
既然加载场景不会释放AssetBundle文件自身的内存镜像,那我们就手动释放。
Destroy:主要用于销毁克隆对象,也可以用于场景内的静态物体,不会自动释放该对象的所有引用。虽然也可以用于Asset,但是概念不一样要小心,如果用于销毁从文件加载的Asset对象会销毁相应的资源文件!但是如果销毁的Asset是Copy的或者用脚本动态生成的,只会销毁内存对象。
AssetBundle.Unload(false):释放AssetBundle文件内存镜像
AssetBundle.Unload(true):释放AssetBundle文件内存镜像同时销毁所有已经Load的Assets内存对象
Reources.UnloadAsset(Object):显式的释放已加载的Asset对象,只能卸载磁盘文件加载的Asset对象
Resources.UnloadUnusedAssets:用于释放所有没有引用的Asset对象
GC.Collect()强制垃圾收集器立即释放内存 Unity的GC功能不算好,没把握的时候就强制调用一下
场景A切换到场景B,使用同步加载Application.LoadLevel(sceneName)或者异步加载Application.LoadLevelAsync(sceneName)都可以。
我们可以在场景A和场景B之间插入一个清理内存的场景X,场景X就是一个空场景,它的主要作用是承上启下,把场景A留下的资源清理,然在切换到场景B。
可以这个功能封装起来。
文章链接:
http://game.ceeger.com/forum/read.php?tid=4394
http://game.ceeger.com/forum/read.php?tid=4466
Unity系统在加载新场景时,所有的内存对象都会被自动销毁,包括你用AssetBundle.Load加载的对象和Instaniate克隆的。
但是不包括AssetBundle文件自身的内存镜像,那个必须要用Unload来释放,用.net的术语,这种数据缓存是非托管的。
既然加载场景不会释放AssetBundle文件自身的内存镜像,那我们就手动释放。
Destroy:主要用于销毁克隆对象,也可以用于场景内的静态物体,不会自动释放该对象的所有引用。虽然也可以用于Asset,但是概念不一样要小心,如果用于销毁从文件加载的Asset对象会销毁相应的资源文件!但是如果销毁的Asset是Copy的或者用脚本动态生成的,只会销毁内存对象。
AssetBundle.Unload(false):释放AssetBundle文件内存镜像
AssetBundle.Unload(true):释放AssetBundle文件内存镜像同时销毁所有已经Load的Assets内存对象
Reources.UnloadAsset(Object):显式的释放已加载的Asset对象,只能卸载磁盘文件加载的Asset对象
Resources.UnloadUnusedAssets:用于释放所有没有引用的Asset对象
GC.Collect()强制垃圾收集器立即释放内存 Unity的GC功能不算好,没把握的时候就强制调用一下
场景A切换到场景B,使用同步加载Application.LoadLevel(sceneName)或者异步加载Application.LoadLevelAsync(sceneName)都可以。
我们可以在场景A和场景B之间插入一个清理内存的场景X,场景X就是一个空场景,它的主要作用是承上启下,把场景A留下的资源清理,然在切换到场景B。
可以这个功能封装起来。
using System; using UnityEngine; using System.Collections; using System.Runtime.CompilerServices; using Object = UnityEngine.Object; public class ClearSceneData : MonoBehaviour { //异步对象 private AsyncOperation async; //下一个场景的名称 private static string nextSceneName; void Awake() { Object[] objAry = Resources.FindObjectsOfTypeAll<Material>(); for (int i = 0; i < objAry.Length; ++i) { objAry[i] = null;//解除资源的引用 } Object[] objAry2 = Resources.FindObjectsOfTypeAll<Texture>(); for (int i = 0; i < objAry2.Length; ++i) { objAry2[i] = null; } //卸载没有被引用的资源 Resources.UnloadUnusedAssets(); //立即进行垃圾回收 GC.Collect(); GC.WaitForPendingFinalizers();//挂起当前线程,直到处理终结器队列的线程清空该队列为止 GC.Collect(); } void Start() { StartCoroutine("AsyncLoadScene", nextSceneName); } /// <summary> /// 静态方法,直接切换到ClearScene,此脚本是挂在ClearScene场景下的,就会实例化,执行资源回收 /// </summary> /// <param name="_nextSceneName"></param> public static void LoadLevel(string _nextSceneName) { nextSceneName = _nextSceneName; Application.LoadLevel("ClearScene"); } /// <summary> /// 异步加载下一个场景 /// </summary> /// <param name="sceneName"></param> /// <returns></returns> IEnumerator AsyncLoadScene(string sceneName) { async = Application.LoadLevelAsync(sceneName); yield return async; } void OnDestroy() { async = null; } }
相关文章推荐
- UNITY 5.2 PlayerPrefs类
- Unity3D研究院之DontDestroyOnLoad的坑
- Unity 客户端知识体系
- unity中对于scrollview下拉加载的方法
- Unity中单例模式的使用
- Unity3D之AssetBundle资源加载封装
- 新手引导
- Unity3DAssetBundle的坑
- 增强现实(AR)笔记:Vuforia及Unity3D
- unity抛物线,平均速度下的运动轨迹
- Unity如何将包缩小到极致
- 自学Unity之做一个MOBA游戏4——小兵
- unity之RotateAround 一个物体围绕另外一个物体旋转
- OccTransVF
- XRay7
- UNITY 5.2 Application类
- Xray6
- Unity Shader入门
- 【Unity】模型高度计算
- unity3d中ProtoBuf的序列化和反序列化c#