zoukankan      html  css  js  c++  java
  • Unity在场景切换之间清理下内存

    看了两篇关于Unity加载和内存管理的文章,写得很详细。
    文章链接:
     

     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。
     
    可以这个功能封装起来。
     
     1 using System;
     2 using UnityEngine;
     3 using System.Collections;
     4 using System.Runtime.CompilerServices;
     5 using Object = UnityEngine.Object;
     6 
     7 public class ClearSceneData : MonoBehaviour
     8 {
     9     //异步对象
    10     private AsyncOperation async;
    11 
    12     //下一个场景的名称
    13     private static string nextSceneName;
    14 
    15     void Awake()
    16     {
    17         Object[] objAry = Resources.FindObjectsOfTypeAll<Material>();
    18 
    19         for (int i = 0; i < objAry.Length; ++i)
    20         {
    21             objAry[i] = null;//解除资源的引用
    22         }
    23 
    24         Object[] objAry2 = Resources.FindObjectsOfTypeAll<Texture>();
    25 
    26         for (int i = 0; i < objAry2.Length; ++i)
    27         {
    28             objAry2[i] = null;
    29         }
    30 
    31         //卸载没有被引用的资源
    32         Resources.UnloadUnusedAssets();
    33 
    34         //立即进行垃圾回收
    35         GC.Collect();
    36         GC.WaitForPendingFinalizers();//挂起当前线程,直到处理终结器队列的线程清空该队列为止
    37         GC.Collect();
    38 
    39     }
    40 
    41     void Start()
    42     {
    43         StartCoroutine("AsyncLoadScene", nextSceneName);
    44     }
    45 
    46     /// <summary>
    47     /// 静态方法,直接切换到ClearScene,此脚本是挂在ClearScene场景下的,就会实例化,执行资源回收
    48     /// </summary>
    49     /// <param name="_nextSceneName"></param>
    50     public static void LoadLevel(string _nextSceneName)
    51     {
    52         nextSceneName = _nextSceneName;
    53         Application.LoadLevel("ClearScene");
    54     }
    55 
    56     /// <summary>
    57     /// 异步加载下一个场景
    58     /// </summary>
    59     /// <param name="sceneName"></param>
    60     /// <returns></returns>
    61     IEnumerator AsyncLoadScene(string sceneName)
    62     {
    63         async = Application.LoadLevelAsync(sceneName);
    64         yield return async;
    65     }
    66 
    67     void OnDestroy()
    68     {
    69         async = null;
    70     }
    71     
    72 }
  • 相关阅读:
    SpringCloud Zipkin快速开始
    Spring-Cloud-Gateway Predicate谓词(断言)使用与自定义
    Gateway Redis令牌桶请求限流过滤器
    SpringBoot集成logback日志组件
    Java使用Aspose-Words实现Word转换Pdf
    JAVA通过Map拼接SQL语句(Insert Update语句)
    使用Java反射机制将Bean对象转换成Map(驼峰命名方式 — 下划线命名方式)
    mybatis执行原生sql
    windows环境下elasticsearch安装教程(超详细)
    购物车的原理及Java实现(仿京东实现原理)
  • 原文地址:https://www.cnblogs.com/dongz888/p/4920714.html
Copyright © 2011-2022 走看看