Unity动态加载与内存关系1:prefab篇

网上得来终觉浅,绝知程序要亲测。好不容易有点闲暇时间,打算把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/[email protected]/manual/index.html

原因是Memory Profiler分析起来更麻烦一些:

Unity动态加载与内存关系1:prefab篇_第1张图片

 

下面是试验过程与数据,有兴趣的可以看看。否则只看上面结论就好了~

首先给摄像机挂上测试脚本,并且拖拽好已经准备好的prefab,到这个脚本组件上:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// 
/// 设计编写:常成功
/// 创建时间:2020/05/08
/// 脚本功能:测试prefab的动态加载与卸载
/// 挂载位置:默认场景的摄像机上
/// 


public class Test_Mem_Add_Sub : MonoBehaviour
{
    // 编辑器静态赋值(拖拽prefab)的测试
    public List pref_list;
    public List 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();
        }
    }
}

 

 

然后,下面是试验截图:

基础内存数据,作为 基本参考值:

Unity动态加载与内存关系1:prefab篇_第2张图片

挂上测试脚本后,运行:

Unity动态加载与内存关系1:prefab篇_第3张图片

依次实例化:

Unity动态加载与内存关系1:prefab篇_第4张图片

2

Unity动态加载与内存关系1:prefab篇_第5张图片

3

Unity动态加载与内存关系1:prefab篇_第6张图片

4

Unity动态加载与内存关系1:prefab篇_第7张图片

5

Unity动态加载与内存关系1:prefab篇_第8张图片

下面开始destroy:

Unity动态加载与内存关系1:prefab篇_第9张图片

d2

Unity动态加载与内存关系1:prefab篇_第10张图片

d3

Unity动态加载与内存关系1:prefab篇_第11张图片

d4

Unity动态加载与内存关系1:prefab篇_第12张图片

d5

Unity动态加载与内存关系1:prefab篇_第13张图片

调用Resources.UnloadUnusedAssets()

Unity动态加载与内存关系1:prefab篇_第14张图片

 

再次运行测试,专门测试Resources.UnloadUnusedAssets()

Unity动态加载与内存关系1:prefab篇_第15张图片

R结果

Unity动态加载与内存关系1:prefab篇_第16张图片

 

你可能感兴趣的:(Unity,架构)