Unity中的GC以及优化

https://blog.csdn.net/worisaa/article/details/64121436
https://zhuanlan.zhihu.com/p/21328671

自创建这个博客,再次转回来已经是5.11号了。
时隔多日,我们重新写这个博客。

1、struct是否有gc
2、如何在unity的profile中查看gc的量

第1、测试类

using UnityEngine;
using UnityEngine.Profiling;

public class StructGCTest : MonoBehaviour
{
     
    public struct Student
    {
     
    }

    private void Update()
    {
     
        if (Input.GetKeyDown(KeyCode.A)) //按下A键,创建一个实例。
        {
     
            Profiler.BeginSample("nihaoxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
            xxxxxxxxxxxxxxxxxxx();
            Profiler.EndSample();
        }
    }

    private void xxxxxxxxxxxxxxxxxxx()
    {
     
        for (int i = 0; i < 1; ++i)
        {
     
            Student s = new Student();
        }
    }
}

代码很简单。重点来喽!
如何在在profile中,查看这个函数的调用呢?
第一步:打开profile,勾选要检测的对象,我们看下cpu和memory的:
Unity中的GC以及优化_第1张图片
Unity中的GC以及优化_第2张图片
我们分别勾选cpu usage的scripts和garbargecollection以及memory的total gc allocated和gc allocated。

第二步:选择CPU Usage,在检索框输入:我们的Profiler.BeginSample的key值:
Profiler.BeginSample(“nihaoxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”);
nihaoxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Unity中的GC以及优化_第3张图片
可以看到此时:
Unity中的GC以及优化_第4张图片
界面上没有我们的检索结果。

第三步:按下A键,创建一个实例。
Unity中的GC以及优化_第5张图片
我们再来看看,是否能够使用暂停程序的方式,不要上面匆忙的方式。移动光标,又啥啥的。
测试代码改为:

using UnityEditor;
using UnityEngine;
using UnityEngine.Profiling;
using System;
using System.Collections;

public class StructGCTest : MonoBehaviour
{
     
    public struct Student
    {
     
    }
    private void Update()
    {
     
        if (Input.GetKeyDown(KeyCode.A))
        {
     
            Profiler.BeginSample("nihaoxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
            xxxxxxxxxxxxxxxxxxx();
            Profiler.EndSample();
        }
    }

    private void xxxxxxxxxxxxxxxxxxx()
    {
     
        for (int i = 0; i < 1; ++i)
        {
     
            Student s = new Student();
        }
        StartCoroutine(StopApplication());    //1秒之后暂停。
    }

    IEnumerator StopApplication()
    {
     
        yield return new WaitForSeconds(1.0f);
        EditorApplication.isPaused = true;
    }

}

Unity中的GC以及优化_第6张图片
Unity中的GC以及优化_第7张图片
Unity中的GC以及优化_第8张图片
如果我们将student换为class:

 public class Student
 {
     
 }

Unity中的GC以及优化_第9张图片

using UnityEditor;
using UnityEngine;
using UnityEngine.Profiling;
using System;
using System.Collections;

public class StructGCTest : MonoBehaviour
{
     
    public class Student
    {
     
    }
    private void Update()
    {
     
        if (Input.GetKeyDown(KeyCode.A))
        {
     
            Profiler.BeginSample("nihaoxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
            xxxxxxxxxxxxxxxxxxx();
            Profiler.EndSample();
        }
    }

    private void xxxxxxxxxxxxxxxxxxx()
    {
     
        for (int i = 0; i < 2000; ++i) //创建2000个对象
        {
     
            Student s = new Student();
        }
        StartCoroutine(StopApplication());   
    }

    IEnumerator StopApplication()
    {
     
        yield return new WaitForSeconds(1.0f);
        EditorApplication.isPaused = true;
    }

}

改为创建10个对象:

   private void xxxxxxxxxxxxxxxxxxx()
    {
     
        for (int i = 0; i < 10; ++i)
        {
     
            Student s = new Student();
        }
        StartCoroutine(StopApplication());   
    }

Unity中的GC以及优化_第10张图片
这里变为了13个调用,有gc。

ok,可以发现当struct作为单独的对象创建时,没有gc。
协程作为辅助产品,也出现了gc,上面的测试代码,用来暂停的时候,可以发现,有gc的。慎用协程。

using UnityEditor;
using UnityEngine;
using UnityEngine.Profiling;
using System;
using System.Collections;

public class StructGCTest : MonoBehaviour
{
     
    public struct People
    {
     
        public Student s;
    }

    public class Student
    {
     
    }
    private void Update()
    {
     
        if (Input.GetKeyDown(KeyCode.A))
        {
     
            Profiler.BeginSample("nihaoxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
            xxxxxxxxxxxxxxxxxxx();
            Profiler.EndSample();
        }
    }

    private void xxxxxxxxxxxxxxxxxxx()
    {
     
        for (int i = 0; i < 10; ++i)
        {
     
            People s = new People();
        }
        StartCoroutine(StopApplication());   
    }

    IEnumerator StopApplication()
    {
     
        yield return new WaitForSeconds(1.0f);
        EditorApplication.isPaused = true;
    }

}

Unity中的GC以及优化_第11张图片
稍作变换:

private void xxxxxxxxxxxxxxxxxxx()
    {
     
        for (int i = 0; i < 100; ++i)
        {
     
            People s = new People();
            s.s = new Student(); //结构体的成员是类,并且new出来了,那么此时这个类成员,在堆上,有gc
        }
        StartCoroutine(StopApplication());   
    }

Unity中的GC以及优化_第12张图片

总结:
1、结构体单独存在,无gc
2、结构体在类中,和普通的值类型,一样,也分配在堆上,在类被gc的时候,结构体占用的内存也被回收。
3、类单独存在,类在结构体中作为成员,都有gc。

你可能感兴趣的:(Unity)