为确保应用程序在运行时没有性能问题,必须了解 Unity 如何使用和分配内存。本文档的这一部分将介绍内存在 Unity 中的工作方式,面向希望了解如何提高应用程序内存性能的读者。
Unity 使用三个内存管理层来处理应用程序中的内存:
Mono 和 IL2CPP 的脚本虚拟机 (VM) 实现了托管内存系统,该系统有时也称为脚本内存系统。这些 VM 提供了分为以下不同类型的受控内存环境:
由于托管内存系统使用 VM,所以它有一个受控环境,可自动跟踪分配的引用以管理分配的生命周期。这意味着在其他代码正在尝试访问内存时,应用程序不太可能过早释放内存。这也意味着可以在一定程度上防止在代码无法访问内存或未使用的内存堆积时发生的内存泄漏。
在 Unity 中使用托管内存是管理应用程序中内存的最简单方法;但它也有一些缺点。垃圾收集器使用起来很方便,但它在释放和分配内存的方式上也难以预测,这可能会导致性能问题,例如垃圾收集器不得不停止以释放和分配内存时出现的卡顿。要解决这种不可预测性,可以使用 C# 非托管内存层。
有关托管内存工作方式的更多信息,请参阅有关托管内存的部分。
C# 非托管内存层有助于访问本机内存层以微调内存分配,同时方便编写 C# 代码。
可以使用 Unity Core API 中的 Unity.Collections 命名空间(包括 NativeArray)以及 Unity Collections 包中的数据结构来访问 C# 非托管内存。如果使用 Unity 的 C# 作业系统或 Burst,则必须使用 C# 非托管内存。如需了解更多相关信息,请参阅有关作业系统和 Burst 的文档。
Unity 引擎的内部 C/C++ 核心有自己的内存管理系统,称为本机内存。在大多数情况下,无法直接访问或修改此内存类型。
Unity 将场景存储在项目、资源、图形 API、图形驱动程序、子系统和插件缓冲区中,并将分配存储在本机内存中,这意味着可以通过 Unity 的 C# API 间接访问本机内存。这意味着可以安全轻松地操控应用程序的数据,而不会丧失 Unity 本机核心上的原生代码和高性能代码的优势。
在大多数情况下,不需要与 Unity 的本机内存交互,但无论何时使用性能分析器,都可以通过性能分析器标记看到它对应用程序性能的影响。还可以通过更改 Unity 本机内存分配器的一些可配置设置来调整应用程序的性能。有关更多信息,请参阅有关本机内存的部分。