Version: 6000.3
语言: 中文
NativeContainer 简介
复制 NativeContainer 结构

实现自定义本机容器

要实现自定义本机容器,您必须使用NativeContainer属性。您还应该了解本机容器如何与安全系统集成。

有两个主要要素需要实现:

  • 使用情况跟踪:允许 Unity 跟踪使用NativeContainer实例,以便它可以检测和防止潜在的冲突,例如两个作业同时写入同一个本机容器。
  • 泄漏跟踪:检测NativeContainer没有得到妥善处理。在这种情况下,会发生内存泄漏,其中分配给NativeContainer在程序的整个剩余生存期内变得不可用。

实现使用情况跟踪

要访问代码中的使用情况跟踪,请使用AtomicSafetyHandle类。AtomicSafetyHandle保存对安全系统为给定本机容器存储的中心信息的引用,并且是NativeContainer与安全系统交互。因此,每个NativeContainer实例必须包含一个AtomicSafetyHandle名为m_Safety.

AtomicSafetyHandle存储一组标志,指示在当前上下文中可以对本机容器执行哪些类型的作。当作业包含NativeContainer实例中,作业系统会自动配置AtomicSafetyHandle以反映本机容器在该作业中的使用方式。

当作业尝试从NativeContainer实例时,作业系统调用CheckReadAndThrow方法,以确认作业具有对本机容器的读取访问权限。同样,当作业尝试写入本机容器时,作业系统会调用CheckWriteAndThrow在写入之前,检查作业是否具有对本机容器的写入访问权限。已分配相同的两个作业NativeContainer实例有单独的AtomicSafetyHandle对象,因此尽管它们都引用了同一组中心信息,但它们都可以保存单独的标志,指示每个作业对本机容器的读取和写入访问权限。

实施泄漏跟踪

Unity 的原生代码主要实现泄漏跟踪。它使用UnsafeUtility.MallocTracked分配存储所需内存的方法NativeContainerdata,然后使用UnsafeUtility.FreeTracked处理它。

在早期版本的 Unity 中,DisposeSentinel类提供泄漏跟踪。当垃圾回收器收集DisposeSentinel对象。要创建DisposeSentinel,使用Create方法,该方法还初始化了AtomicSafetyHandle同时。使用此方法时,无需初始化AtomicSafetyHandle.当NativeContainer被处置,则Dispose方法将DisposeSentinelAtomicSafetyHandle在一次通话中。

确定泄漏的位置NativeContainer创建时,您可以捕获最初分配内存的位置的堆栈跟踪。为此,请使用NativeLeakDetection.Mode财产。你还可以在编辑器中访问此属性。为此,请转到首选项>作业>泄漏检测级别,然后选择您需要的泄漏检测级别。

嵌套的本机容器

安全系统不支持作业中的嵌套本机容器,因为作业系统无法正确配置AtomicSafetyHandle对于每个人NativeContainer在较大的NativeContainer实例。

要防止调度使用嵌套本机容器的作业,请使用SetNestedContainer,它标记了一个NativeContainer当它们包含其他NativeContainer实例。

安全 ID 和错误消息

安全系统会提供错误消息,指示您的代码何时不遵守安全约束。为了帮助使错误消息更清晰,您可以注册一个NativeContainer对象的名称与安全系统。

要注册名称,请使用NewStaticSafetyId,它返回一个安全 ID,您可以传递给SetStaticSafetyId.创建安全 ID 后,您可以将其重复用于NativeContainer,因此常见的模式是将其存储在容器类的静态成员中。

您还可以使用SetCustomErrorMessage.

其他资源

NativeContainer 简介
复制 NativeContainer 结构