当前位置: 首页 > news >正文

Unity-GC详解

什么是GC呢?

简单的说,Unity的GC就是一个专门针对动态内存(堆内存)进行自动回收的机制(Garbge Collector)

但是这里,我们就要说清楚一些Unity和C#的更低层次的东西了:

我们都知道Unity是用C#写成的,或者说我们的源码是C#构成的,按照正常的流程,我们要将代码进行编译后再汇编才能变成机器可以阅读的机器码。其中关于这个编译方法主要有两种:

可以看到两种编译方式的主要区别就在于CIL(中间语言)到机器码之间的这个过程,Mono方案是生成JIT/AOT而IL2CPP是生成C++,具体区别如图所示,简单的说就是Mono最大的好处就是支持热更新,其他不论性能还是安全性IL2CPP都更高一筹。

所以我们来讨论IL2CPP的情况下我们的GC:

所以我们真正的主角就是:Boehm GC

比较直白地说,我们的Bohem GC的运行原理就是遍历所有内存区域(如线程栈、全局变量、寄存器),将其中 ​符合地址范围和对齐规则​ 的数值视为 ​潜在指针,这些潜在指针指向的动态内存就是活跃对象,最后将所有的不活跃内存回收。

Bohem GC和C#/JAVA的GC以及Lua的GC的区别:

Bohem GC优化点:

一般来说,GC只负责回收堆上的内存,但是我们如果换个角度想:我们什么时候会去回收内存呢?往往是我们在堆上分配了一块新的内存,虽然二者并不是强关联关系,但是确实客观上存在可能。

因此,我们现在去考虑考虑哪些场景会导致我们的GC:

首先,C#中涉及到堆,我们很容易想到:

装箱:

装箱时,我们需要将原本存储在栈上的值类型复制到堆上开辟的新内存上,变成引用类型。这个过程中涉及到堆内存的分配,比如我们要是频繁进行装箱的话就会引发GC。

针对这种情况,我们最好的优化思路就是去减少装箱:这是我们的一个核心理念。

比如我们的泛型:

匿名方法:

我们都知道匿名方法在通过闭包捕获外部变量时,会生成一个匿名类,既然涉及到类(引用类型)那自然就会涉及到堆内存的分配,那么自然就会涉及到GC了。

int n = 1;
void Test()     
{Call(()=> n = 2);     
}

那么要如何去优化呢?

一般来说,我们可以把匿名方法要捕获的对象写成静态的,这样就不用生成匿名类来存储这个捕获的变量了(静态变量等同于类,直接通过类名访问);

static int n = 1; // 静态变量
void Func() {Call(() => n = 2); // 匿名方法直接访问静态变量
}

我们还可以利用委托来缓存匿名方法,这样我们只用在第一次调用委托时生成匿名类,后续我们就一直调用委托缓存中的匿名方法,不会生成新的匿名类。

int a = 1;          // 实例变量
Action action;      // 缓存委托实例
void Func() {if (action == null) { // 首次初始化委托action = () => a = 2; // 生成闭包(仅一次)}Call(action);    // 复用缓存的委托实例
}

字符串:

我们都知道C#中的string本身是不可变的,任何对string类型变量的操作都需要先复制一个源字符串再进行操作,那么这个时候旧的字符串就变成了无人使用的内存垃圾。

虽然当我们提到关于修改string类型对象的思路一般都是使用stringbuilder,但是实际上stringbuilder并没有那么好用,我们可以去使用一些其他的优化方法。

类和结构体:

这个就是基本都能想到的:结构体是值类型而类是引用类型,对于并不庞大的数据,能使用结构体的话优先使用结构体,不会涉及到堆上内存的分配就不会引发GC。

容器:

大多数我们使用的容器都支持动态扩容,那么每次动态扩容都会涉及到堆上的内存分配,所以尽可能地我们去减少容器的扩容。

Unity的GC和C#的GC对比:

相关文章:

  • 机器学习逻辑回归损失函数与正则化技术深度解析
  • 网络协议之详解(Detailed Explanation of Network Protocol)
  • 第33周JavaSpringCloud微服务 面试题
  • 【数据可视化-21】水质安全数据可视化:探索化学物质与水质安全的关联
  • Qt开发:软件崩溃时,如何生成dump文件
  • ffmpeg 硬解码相关知识
  • Spring之我见 - Spring MVC重要组件和基本流程
  • 开启报名!火山引擎 x PICO-全国大学生物联网设计竞赛赛题发布
  • 【MATLAB第117期】#源码分享 | 基于MATLAB的SSM状态空间模型多元时间序列预测方法(多输入单输出)
  • 【随手记】jupyter notebook绘制交互式图像
  • Shell循环语句---for和while
  • 【上海大学数据库原理实验报告】MySQL数据库的C/S模式部署
  • 发送百度地图的定位
  • 物联网蓬勃发展是助力楼宇自控技术迈向成熟的关键
  • AI 健康小屋:开启智慧健康管理新范式
  • # 06_Elastic Stack 从入门到实践(六)
  • ffmpeg av_buffer_unref的逻辑实现; av_freep 和 av_freep函数的区别
  • 用c语言实现——一个带头节点的链队列,支持用户输入交互界面、初始化、入队、出队、查找、判空判满、显示队列、遍历计算长度等功能
  • 神经网络权重优化秘籍:梯度下降法全解析(五)
  • 记录一次使用面向对象的C语言封装步进电机驱动
  • 网培机构围猎中老年人:低价引流卖高价课、“名师”无资质,舆论呼吁加强监管
  • 特朗普施压鲍威尔遭多方批评,分析人士:特朗普若解雇鲍威尔或冲击美债
  • 被指违反代理协议遭南航暂停售票资格, 去哪儿网:今起恢复
  • 人民日报头版开新栏:收官之年干劲满,决战决胜勇争先
  • 独家专访|苏童:《好天气》是一部献给中国郊区的作品
  • 纪念沈渭滨︱志于道而游曳于士和氓间的晚年沈先生