Garbage:内存被不会被使用的数据占据。
Garbage collection:使上述内存能够被使用。
1)核心引擎代码:使用手动内存管理,不使用垃圾回收。
2)用户代码:使用自动内存管理,不需要知道内存管理细节
1)两种内存池:栈(stack)、堆(heap 托管堆)
2)变量在使用范围内时,存储它的内存被分配(allocated)
3)变量超出使用范围时,存储它的内存被重新分配(deallocated)
① 栈:变量在超出使用范围后,占用内存立即被重新分配
② 堆:变量在超出使用范围后,占用内存仍然保持被分配状态
4)垃圾回收器(garbage collector)周期性地标记、重新分配不被使用的堆内存。
1)存储周期短、小块数据
2)按照后进后出的方式压栈、出栈
3)变量在超出使用范围后,内存立即被重新分配
1)推荐存储周期长、大块数据;也可存储周期短、小块数据
2)值类型变量存储在栈上,其他变量存储在堆上()
3)堆变量被创建时:
① Unity 检查堆中是否有足够内存空间,如果足够,则分配内存;
② 如果不够,则触发GC(比较耗时)。如果GC后内存足够,则分配内存;
③ 如果GC后内存还不够,则扩充堆内存空间(比较耗时),然后分配内存。
4)堆内存只能被GC重新分配;GC只作用于堆内存
1)GC执行步骤:
① 检测堆上的每个对象
② 搜索所有对象的引用,检测是否在有效范围内
③ 不在有效范围内的对象,被标记为待清除
④ 被标记的对象被清除,内存被重新分配(返还给堆)
补充:堆上对象越多、代码中引用的对象越多,GC越耗时。
2)GC执行时机:
① 堆内存没有足够空间分配给新变量
② 由目标平台决定的,定期执行
③ 手动执行
补充:第①步可能造成频繁GC
3)GC引起的问题:
① 耗时导致的卡顿
② 在不恰当的时机GC,影响游戏表现及降帧
③ 堆内存碎片化,占用内存虚高,频繁GC
1)三种方式:
① 减少GC执行时间
② 减少GC执行频率
③ 在恰当时机手动调用GC
1)三种策略:
① 减少堆分配、对象引用数量
② 减少堆分配、重新分配频率
③ 在恰当时机手动调用GC
1)减少垃圾数量
① 使用缓存:避免重复的分配、重新分配
② 减少在 Update 这种频繁调用的方法中分配堆内存
③ 使用 Clear 清理集合,而不是每次生成
④ 对象池
2)常见的不必要的堆内存分配
① String:它是不可变的,每次更改都是创建一个新对象。
② Unity方法不恰当的调用
③ 装箱:把值类型变量当引用类型使用,将创建一个临时 Object 封装值类型变量
④ Coroutines
⑤ 方法引用
3)从代码架构上避免不必要的GC检测:
原文:https://www.cnblogs.com/hearthstone/p/13357925.html