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的:
在这里插入图片描述
在这里插入图片描述
我们分别勾选cpu usage的scripts和garbargecollection以及memory的total gc allocated和gc allocated。

第二步:选择CPU Usage,在检索框输入:我们的Profiler.BeginSample的key值:
Profiler.BeginSample(“nihaoxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx”);
nihaoxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
在这里插入图片描述
可以看到此时:
在这里插入图片描述
界面上没有我们的检索结果。

第三步:按下A键,创建一个实例。
在这里插入图片描述
我们再来看看,是否能够使用暂停程序的方式,不要上面匆忙的方式。移动光标,又啥啥的。
测试代码改为:

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;
    }

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如果我们将student换为class:

 public class Student
 {
 }

在这里插入图片描述

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());   
    }

在这里插入图片描述
这里变为了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;
    }

}

在这里插入图片描述
稍作变换:

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

在这里插入图片描述

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

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值