目录
🟥 一、什么是内存?
1.物理内存
2.虚拟内存
🟧 二、Unity的内存
1.Unity的内存分类
2.游戏运行时内存占用情况
3.什么是MONO内存?
4.内存碎片、僵尸内存
🟨三、GC 垃圾回收
1.定义
2.一张图清晰得看一下流程~
3.GC的作用及步骤
4.GC存在的问题及优化策略
🟩 四、内存优化的具体建议
1.本机内存的优化
2.优化托管内存
3.图像的一些优化建议
4.UI的一些优化建议
5.其他的一些优化建议
🟥 一、什么是内存?
内存分为物理内存、虚拟内存
1.物理内存
也就是我们真是的硬件设备,例如内存条。
****这里引出一个概念:我们需要知道,CPU访问内存是一个慢速过程。***
访问过程具体为:先访问Cache,Cache包含L1,L2,L3,也就是一级缓存,二级缓存和三级缓存,若在这些缓存里全没找到我们要的数据,再去访问内存,接着会把找到的数据存放到Cache中,完成一次操作。
在Cache中没有找到数据,我们称之为Cache Miss。因此过多的Cache Miss就会导致大量的内存和Cache的IO交换,浪费大量时间。
因此我们需要尽量减少Cache Miss,来提高访问速度,Unity为此提出了ECS方案,它们可以将存储在内存中的不连续数据,变为连续的数据,从而降低Cache Miss的概率。
2.虚拟内存
虚拟内存是利用磁盘空间虚拟出的一块逻辑内存,用作虚拟内存的磁盘空间被称为交换空间(Swap Space)。
🟧 二、Unity的内存
1.Unity的内存分类
2.游戏运行时内存占用情况
3.什么是MONO内存?
4.内存碎片、僵尸内存
这里我引用了Unity官方视频里的两张图片及以为说明
Unity官方浅谈内存管理
A.采用分区式存储管理的系统,在储存分配过程中产生的、不能供用户作业使用的主存里的小分区称成“内存碎片”。例: 现在可用内存空间为3,但是,这3个空闲空间,并不是连续的。 所以,如果程序现在申请长度为3的内存空间,同样会申请不了,会出现内存不够的情况。
B.内存泄漏(僵尸内存)产生的原因比较简单明确,就是申请的内存已经不需要再次被使用了,但是并没有归还给内存分配器(管理器)或者系统。
🟨三、GC 垃圾回收
1.定义
在Unity中,GC(Garbage Collection,垃圾回收)是一种自动内存管理机制,它负责在运行时检测和清理不再使用的对象,以便释放内存资源。
2.一张图清晰得看一下流程~
、
3.GC的作用及步骤
GC的主要作用在于从已用内存中找出那些不再需要使用的内存,并进行释放。
Mono中的GC主要有以下几个步骤:
1.停止所有需要mono内存分配的线程。
2.遍历所有已用内存,找到那些不再需要使用的内存,并进行标记。
3.释放被标记的内存到空闲内存。
4.重新开始被停止的线程。
4.GC存在的问题及优化策略
🟩 四、内存优化的具体建议
1.本机内存的优化
Scene
导致Native Memory增长的原因,最常见的就是Scene。因为是c++引擎,所有的实体最终都会反映在c++上,
而不会反映在托管堆上。所以当我们构建一个GameObject的时候,实际上在Unity的底层会构建一个或多个object来存储这一个GameObject的信息(Component信息等)。所以当一个Scene里面有过多GameObject存在的时候,Native Memory就会显著的上升,甚至可能导致内存溢出。
注:当我们发现Native Memory大量上升时,可以先着重检查我们的Scene。
Resource
Resource文件夹里的内容被打进包的时候会做一个红黑树(R-B Tree)用做索引,即检索资源到底在什么位置。所以Resource越大,红黑树越大,它不可卸载,并在刚刚加载游戏的时候就会被一直加在内存里,极大的拖慢游戏的启动时间,因为红黑树没有分析和加载完,游戏是不会启动的,并造成持续的内存压力。所以建议不要使用Resource,使用AssetBundle。
2.优化托管内存
Destroy与null
用Destroy,别用null,显示的调用Destroy才能真正的销毁掉。
Destroy与null
用Destroy,别用null,显示的调用Destroy才能真正的销毁掉。
减少装箱拆箱操作
例如LINQ和常量表达式以装箱的方式实现,String.Format()也常常会产生装箱操作等
对象池
虽然VM自己有内存池,但是我们还是需要自己使用内存池来管理。
闭包和匿名函数
所有的匿名函数和闭包在c#编IL代码时都会被new成一个Class(匿名class),所以在里面所有函数,变量以及new的东西,都是要占内存的。
协程
协程属于闭包和匿名函数的特例,游戏开始启动一个协程直到游戏结束才释放,错误的做法。因为协程只要没被释放,里面的所有变量,即使是局部变量(包括值类型),也都会在内存里。建议用的时候才生产一个协程,不用的时候就丢掉
配置表
一个游戏,策划往往会通过excel配置很多的配置表,然后我会在游戏中加载这些excel来读取其中的数据。但是如果excel数量非常的庞大,我们最好不要一下子全丢到内存里,建议分关加载等。
单例
慎用单例,且不要什么都往里放,因为里面的变量会一直占用内存。
3.图像的一些优化建议
4.UI的一些优化建议
5.其他的一些优化建议
避免在Awake和Start中添加大量的逻辑
这对游戏启动很重要,Unity会在Awake和Start方法执行后渲染第一个画面,某些情况可能会导致启动画面或是载入画面需要花更长的时间渲染,因为你必须等每个游戏对象都完成Awake和Start的执行。同时若游戏启动时,黑屏太久,提包时可能会被退审。
数据结构
也就是Array,List和Dictionary等,例如在Array或List中使用索引的成本很低,那么就适合要经常通过索引读取的情况。而要频繁增加和移除对象时,使用Dictionary是最合适的。文章来源:https://www.toymoban.com/news/detail-773226.html
感谢大家的观看,您的点赞和关注是我最大的动力文章来源地址https://www.toymoban.com/news/detail-773226.html
到了这里,关于[Unity]⭐浅谈Unity内存优化,内存碎片?僵尸内存?以及什么是GC垃圾回收机制。的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!