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