Unity3D:内存托管

Unity3D:内存托管
推荐:将NSDT场景编辑器加入你的3D工具链
3D工具集:NSDT简石数字孪生

内存托管

Unity 的托管内存系统是基于 Mono 或 IL2CPP 虚拟机 (VM) 的 C# 脚本环境。托管内存系统的好处是它管理内存的释放,因此您无需通过代码手动请求释放内存。

Unity 的托管内存系统使用垃圾回收器和托管堆,以便在脚本不再包含对这些分配的任何引用时自动释放内存分配。这有助于防止内存泄漏。当分配内存时,会发生内存泄漏,对它的引用丢失,然后永远不会释放内存,因为它需要对它的引用来释放它。

此内存管理系统还保护内存访问,这意味着您无法访问已释放的内存,或者代码访问的内存永远无效。但是,此内存管理过程会影响运行时性能,因为分配托管内存对于 CPU 来说非常耗时。垃圾回收还可能阻止 CPU 执行其他工作,直到完成。

值和引用类型

调用方法时,脚本后端将其参数的值复制到为该特定调用保留的内存区域,该区域位于称为调用堆栈的数据结构中。脚本后端可以快速复制占用几个字节的数据类型。但是,对象、字符串和数组通常要大得多,并且脚本后端定期复制这些类型的数据效率低下。

必须在托管堆上分配托管代码中的所有非 null 引用类型对象和所有装箱值类型的对象。

熟悉值和引用类型非常重要,这样才能有效地管理代码。有关详细信息,请参阅 Microsoft 有关值类型和引用类型的文档。

自动内存管理

创建对象时,Unity 会从称为堆的中央池中分配存储该对象所需的内存,是 Unity 项目所选脚本运行时(Mono 或 IL2CPP)自动管理的内存部分。当一个对象不再使用时,它可以回收它曾经占用的内存并用于其他内容。

Unity 的脚本后端使用垃圾回收器自动管理应用程序的内存,因此您无需通过显式方法调用来分配和释放这些内存块。与显式分配/释放相比,自动内存管理需要更少的编码工作,并减少了内存泄漏的可能性。

托管堆概述

托管堆是 Unity 项目所选脚本运行时(Mono 或 IL2CPP)自动管理的内存部分。

内存量。关系图上标记为 A 的是一些可用内存。
内存量。关系图上标记为 A 的是一些可用内存。

在上图中,蓝色框表示 Unity 分配给托管堆的内存量。其中的白框表示 Unity 存储在托管堆内存空间中的数据值。当需要其他数据值时,Unity 会从托管堆(带注释的 A)中为它们分配可用空间。

内存碎片和堆扩展

内存量,释放的某些对象由灰色虚线表示。
内存量,释放的某些对象由灰色虚线表示。

上图显示了内存碎片的示例。当 Unity 释放对象时,将释放该对象占用的内存。但是,可用空间不会成为单个大型“可用内存”池的一部分。

释放对象两侧的对象可能仍在使用中。因此,释放的空间是其他内存段之间的“间隙”。Unity 只能使用此间隙来存储与发布对象相同或更小大小的数据。

这种情况称为内存碎片。当堆中有大量可用内存,但仅在对象之间的“间隙”中可用时,就会发生这种情况。这意味着,即使有足够的总空间用于大型内存分配,托管堆也无法找到足够大的单个连续内存块来分配给分配。

带注释 A 的对象是需要添加到堆中的新对象。带批注 B 的项目是释放的对象占用的内存空间,加上空闲的、未保留的内存。即使有足够的总可用空间,由于没有足够的连续空间,批注 A 的新对象的内存也无法容纳在堆上,垃圾回收器必须运行。
带注释 A 的对象是需要添加到堆中的新对象。带批注 B 的项目是释放的对象占用的内存空间,加上空闲的、未保留的内存。即使有足够的总可用空间,由于没有足够的连续空间,批注 A 的新对象的内存无法容纳在堆上,垃圾回收器必须运行。

如果分配了一个大型对象,并且没有足够的连续可用空间来容纳它,如上图所示,Unity 内存管理器将执行两个操作:

  • 首先,垃圾回收器运行(如果尚未运行)。这将尝试释放足够的空间来满足分配请求。
  • 如果在垃圾回收器运行后,仍然没有足够的连续空间来容纳请求的内存量,则必须扩展堆。堆扩展的具体量取决于平台;但是,在大多数平台上,当堆扩展时,它会扩展为先前扩展量的两倍。

托管堆扩展注意事项

堆的意外扩展可能会出现问题。Unity 的垃圾回收策略倾向于更频繁地对内存进行碎片化。您应该注意以下几点:

  • Unity 在定期扩展时不会释放分配给托管堆的内存;相反,它保留扩展的堆,即使其中很大一部分是空的。这是为了防止在发生进一步的大分配时需要重新扩展堆。
  • 在大多数平台上,Unity 最终会将托管堆的空部分使用的内存释放回操作系统。无法保证发生这种情况的时间间隔,并且不可靠。

此文由3D建模学习工作室整理翻译,转载请注明出处!

上一篇:Unity3D:Editor 故障排除 (mvrlink.com)

下一篇:Unity3D:内存分配器定制 (mvrlink.com)

NSDT场景编辑器 | NSDT 数字孪生 | GLTF在线编辑器 | 3D模型在线转换 | UnrealSynth虚幻合成数据生成器 | 3D模型自动纹理化工具
2023 power by nsdt©鄂ICP备2023000829号