Unity 使用垃圾收集器从应用程序和 Unity 不再使用的对象中回收内存。当脚本尝试在托管堆上进行分配但没有足够的可用堆内存来容纳分配时,Unity 会运行垃圾收集器。在垃圾收集器运行时,它会检查堆中的所有对象,并标记删除应用程序不再引用的任何对象。Unity 随后会删除未引用的对象,从而释放内存。
垃圾收集器以相同方式处理后续请求,直到没有足够大的可用区域来分配所需的内存块大小。在这种情况下,可能并非所有已分配的内存都仍在使用。只要仍有引用变量可以定位到引用项,那么 Unity 的脚本后端就只可访问堆上的该引用项。如果对内存块的所有引用都消失(即,引用变量已被重新分配,或者引用变量是局部变量但现在已超出作用域),则垃圾收集器可重新分配被占用的内存。
为确定哪些堆内存块已不再使用,垃圾收集器会搜索所有处于活动状态的引用变量,并标记被它们引用为“实时”的内存块。在搜索结束时,垃圾收集器会认为“实时”内存块之间的所有空间均为空,并标记它们以供后续分配。定位和释放未使用内存的过程称为垃圾收集 (GC)。
注意:垃圾收集器的工作方式在 Web 平台上有所不同。有关更多信息,请参阅垃圾收集注意事项。
在 Unity 中,垃圾收集器具有以下模式:
Unity 使用以下工具来跟踪内存分配:
在 CPU 使用量 (CPU Usage) 模块中,层级视图包含一个 GC Alloc 列。此列显示了 Unity 在特定帧中分配在托管堆上的字节数。它还显示垃圾收集器管理的内存量,并且包括 Unity 可能已经分配并在后续帧中重用的内存。这意味着所有帧上的 GC Alloc 的总和不会等于托管内存在这段时间内的增加量。
为了获得最准确的信息,应始终在要构建的目标平台或设备上对开发构建上的应用程序进行性能分析。Unity 编辑器的工作方式与构建不同,这会影响性能分析数据;例如,GetComponent 方法在编辑器中执行时始终会分配内存,但在构建项目中不会。
还可以在性能分析器中使用调用堆栈 (Call Stacks) 模式,以确定分配发生在哪种方法中。可以为 GC.Alloc 样本启用完整的调用堆栈跟踪记录,帮助确定垃圾收集器的运行位置和时间。