网上得来终觉浅,绝知程序要亲测。好不容易有点闲暇时间,打算把unity动态加载的几种方式,以及对应的内存占用/释放,测试一遍。这是第一篇,最简单的prefab的生成与销毁:
本文使用unity2019.3测试。这里分为编辑器的【冷运行】和【热运行】。
编辑器的冷运行:就是编辑器完全退出后,再启动编辑器,再运行程序。
编辑器的热运行:就是在编辑器里,直接运行程序。
冷热运行,profile的结果有出入,所以我怀疑,编辑器在热运行时,是缓存了一部分数据的。哪位朋友知道确切的原理,还望在留言区里不吝赐教,大家一起学习。
先说一下结论:
1, 脚本引用prefab的模式,启动就会加载Mesh,会占用一部分内存。(简单理解,相当于Resources.Load())
2,Instantiate() 的时候,会载入Texture,占用内存。
3,Destroy() 会马上释放小部分显存。Unity等待GC时机,再释放部分mesh和texture资源。但是仍不彻底。
4,Resources.UnloadUnusedAssets() 确实可以清理内存,会把没有使用(或者资源=null)的资源清理掉。注意,官方建议在允许卡顿的情况下调用(比如loading界面),因为这是一个非常缓慢的操作。
下面试验,使用unity自带的profile,内存相关的具体参数,可以看官网解释:
https://docs.unity3d.com/Manual/ProfilerMemory.html
当然也可以使用【Memory Profiler】,但是我测到一半放弃了,参数文档如下:
https://docs.unity3d.com/Packages/com.unity.memoryprofiler@0.2/manual/index.html
原因是Memory Profiler分析起来更麻烦一些:
下面是试验过程与数据,有兴趣的可以看看。否则只看上面结论就好了~
首先给摄像机挂上测试脚本,并且拖拽好已经准备好的prefab,到这个脚本组件上:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 设计编写:常成功
/// 创建时间:2020/05/08
/// 脚本功能:测试prefab的动态加载与卸载
/// 挂载位置:默认场景的摄像机上
/// </summary>
public class Test_Mem_Add_Sub : MonoBehaviour
{
// 编辑器静态赋值(拖拽prefab)的测试
public List<GameObject> pref_list;
public List<GameObject> obj_list;
// 从左至右生成物体,起始点左边
private float last_x = -5.0f;
// 点击计数器
private int click_L_num = 0;
private int click_R_num = 0;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetMouseButtonDown(0))
{
Debug.Log("Mouse L:");
GameObject obj_clone = Instantiate(pref_list[click_L_num]);
// 调整一下位置
last_x = last_x + click_L_num * 1.2f;
obj_clone.transform.position = new Vector3(last_x, 0, 0);
// 记录
click_L_num += 1;
obj_list.Add(obj_clone);
}
else if (Input.GetMouseButtonDown(1))
{
Debug.Log("Mouse R:");
DestroyImmediate(obj_list[click_R_num]);
click_R_num += 1;
}
// 释放已经没有引用的资源
if (Input.GetKeyDown(KeyCode.R))
{
pref_list = null;
obj_list = null;
Debug.Log("Key R:");
Resources.UnloadUnusedAssets();
}
}
}
然后,下面是试验截图:
基础内存数据,作为 基本参考值:
挂上测试脚本后,运行:
依次实例化:
2
3
4
5
下面开始destroy:
d2
d3
d4
d5
调用Resources.UnloadUnusedAssets()
再次运行测试,专门测试Resources.UnloadUnusedAssets()
R结果