一、认识Unity的自动内存管理

Unity Manual:理解自动内存管理

unity应用占用的内存可以分为三类,托管堆、本机堆、引擎及代码自身占用的内存;本篇介绍的自动内存管理即托管堆的管理。

Unity为我们做了一些自动的内存管理操作,但是我们也需要遵守一些规范才能让这种机制更好的发挥作用,所以我们需要了解一下unity自动内存管理究竟做了什么;

我们知道当一个Object,字符串或数组被创建时,计算机会在堆中为其分配内存;但它不在使用的时候,内存就会被回收;在之前都是由开发者分配和释放堆内存,但是运行时runtime system如Unity的Mono,C#的CLR会提供自动的内存管理;

1.值类型和引用类型

值类型:一般占用较少的字节数,传递时直接复制成本较低;

引用类型:如字符串、数组等,直接复制效率非常低,所以在堆中存储,然后通过指针访问,指针自身是存储在栈中的;

2.分配和垃圾收集

内存管理器跟踪它知道的未使用的堆中的区域,当实例化一个对象需要请求内存时,管理器选择一个未使用的内存区域来分配该块,然后从已知的未使用的空间中删除已分配的内存;但是如果已知的可使用的内存不够用了,而实际情况确是,从对分配的所有内存都在使用的可能性很小,我们需要找出那些已经没有被引用的内存块,然后重新分配其占用的内存(注意内存泄漏),这种查找释放的过程就是GC;

每当Unity需要进行GC操作时,它都会停止运行程序代码,并且在GC完成之后工作才能恢复正常运行,这种中断很可能造成游戏延迟,从1ms到上百ms不等,也就是意味着当GC进行时,我们无法维持平滑动画所需要的帧率,这些中断也称为GC峰值,我们可以在Profiler中去观察到;

3.什么是内存分配

首先要了解计算机的存储结构,了解计算机内存的基本概念;

看云-内存基本概念(操作系统)

简书-内存分配

二、进阶

1.unity中具体的内存分配策略

参考:WeTest-内存是手游的硬伤——Unity游戏Mono内存管理及泄漏

Mono通过垃圾回收机制(Garbage Collect,简称GC)对内存进行管理。Mono内存分为两部分,已用内存(used)和堆内存(heap),已用内存指的是mono实际需要使用的内存,堆内存指的是mono向操作系统申请的内存,两者的差值就是mono的空闲内存。当mono需要分配内存时,会先查看空闲内存是否足够,如果足够的话,直接在空闲内存中分配,否则mono会进行一次GC以释放更多的空闲内存,如果GC之后仍然没有足够的空闲内存,则mono会向操作系统申请内存,并扩充堆内存,具体如下图所示。

unity内存分析 unity内存管理机制_内存泄漏

2.内存泄漏

WeTest-深入浅出再谈Unity内存泄漏

Unity下的内存泄漏,主要分为代码侧的泄漏和资源侧的泄漏,当然,资源侧的泄漏也是因为在代码中对资源的不合理引用引起的。

3.性能优化

UWA-性能优化,进无止境-内存篇(上)

https://en.wikipedia.org/wiki/Boehm_garbage_collector