Unity官方文档中关于内存管理的翻译(2021.3)

原文:Memory in Unity - Unity 手册

Unity内存管理

为了确保您的应用程序运行时没有性能问题,了解Unity如何使用和分配内存非常重要。本文档的这一部分解释了Unity中内存是如何工作的,适用于希望了解如何提高应用程序内存性能的读者。

Unity使用三个内存管理层来处理应用程序中的内存:

1. 托管内存:一个受控的内存层,使用托管堆和垃圾收集器来自动分配和分配内存。

2. C#非托管内存:与Unity Collections命名空间和包一起使用的内存管理层。这种内存类型称为“非托管”,因为它不使用垃圾收集器来管理未使用的内存部分。

3. 本地内存:Unity用于运行引擎的C++内存。在大多数情况下,这个内存对Unity用户是不可访问的,但如果您想要微调应用程序性能的某些方面,了解它可能会有用。

托管内存

Mono和IL2CPP的脚本虚拟机(VM)实现了托管内存系统,有时也称为脚本内存系统。这些VM提供了一个受控内存环境,分为以下不同类型:

- 托管堆:VM自动控制的内存部分,使用垃圾收集器(GC)来管理。因此,分配在托管堆上的内存被称为GC分配。分配的任何发生都会在Profiler中记录为GC.Alloc样本。
- 脚本堆栈:当应用程序进入和退出任何代码范围时,堆栈会构建和解开。
- 本地VM内存:包含与Unity的脚本层相关的内存。在大多数情况下,您不需要操作本地VM内存,但了解它包括与代码生成相关的执行代码内存,尤其是关于泛型使用、Reflection使用的类型元数据以及运行VM所需的内存。

由于托管内存系统使用VM,它具有受控环境,自动跟踪分配的引用以管理其生命周期。这意味着您的应用程序不太可能在其他代码尝试访问内存时过早释放内存。这还意味着您对内存泄漏有一些保障,当内存从代码或未使用的内存堆积中不可访问时发生。

在Unity中使用托管内存是管理应用程序内存的最简单方法;但它也有一些缺点。垃圾收集器很方便使用,但在释放和分配内存时的方式不可预测,这可能会导致性能问题,比如当垃圾收集器必须停止释放和分配内存时会发生卡顿。为了解决这种不可预测性,您可以使用C#非托管内存层。

有关托管内存工作原理的更多信息,请参阅托管内存文档。

C#非托管内存

C#非托管内存层允许您访问本地内存层以微调内存分配,同时编写C#代码非常方便。

您可以使用Unity核心API中的Unity.Collections命名空间(包括NativeArray)以及Unity Collections包中的数据结构来访问C#非托管内存。如果您使用Unity的C#作业系统或Burst,您必须使用C#非托管内存。有关更多信息,请参阅作业系统和Burst的文档。

本地内存

Unity引擎的内部C/C++核心具有自己的内存管理系统,称为本地内存。在大多数

情况下,您不能直接访问或修改这种内存类型。

Unity将您项目中的场景、资产、图形API、图形驱动程序、子系统和插件缓冲区以及本地内存内的分配都存储在本地内存中,这意味着您可以通过Unity的C# API间接访问本地内存。这意味着您可以安全且轻松地操作应用程序的数据,而不会失去Unity本地核心中的本地和高性能代码的好处。

大多数情况下,您不需要与Unity的本地内存交互,但每当您使用Profiler时,都可以通过Profiler标记来查看它如何影响应用程序的性能。

原文:Managed memory - Unity 手册

Managed memory

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

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

这个内存管理系统还保护内存访问,这意味着您不能访问已被释放的内存,或者对于您的代码来说从未有效的内存。然而,这个内存管理过程会影响运行时性能,因为分配托管内存对CPU来说是耗时的。垃圾回收也可能会在完成之前阻止CPU执行其他工作。

值类型和引用类型

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

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

熟悉值类型和引用类型对于有效管理代码很重要。有关更多信息,请参阅Microsoft的有关值类型和引用类型的文档。

自动内存管理

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

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

托管堆概述

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

在上面的图表中,蓝色框表示Unity分配给托管堆的一定数量的内存。其中的白色框代表Unity在托管堆的内存空间内存储的数据值。当需要额外的数据值时,Unity会从托管堆(标有A的地方)分配它们的空间。

内存碎片和堆扩展

上图显示了内存碎片的示例。当Unity释放一个对象时,该对象占用的内存会被释放。然而,空闲空间不会成为一个“自由内存”的单一大池。

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

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

(被标注为A的对象是需要添加到堆上的新对象。被标注为B的项目是已释放对象占用的内存空间,以及空闲的未分配内存。尽管总的空闲空间足够,但由于没有足够的连续空间,所以被标注为A的新对象的内存无法适应堆,因此必须运行垃圾收集器。)

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

首先,如果垃圾回收器尚未运行,则运行垃圾回收器。这试图释放足够的空间来满足分配请求。

如果在垃圾回收器运行后,仍然没有足够的连续空间来容纳请求的内存量,则必须扩展堆。堆扩展的具体量取决于平台,但在大多数平台上,当堆扩展时,它会扩展到前一次扩展的两倍。

托管堆扩展注意事项

堆意外扩展可能会引发问题。Unity的垃圾收集策略倾向于更频繁地碎片化内存。您应该注意以下事项:

Unity不会在定期扩展堆时释放分配给托管堆的内存;相反,它会保留扩展的堆,即使其中的大部分部分为空。这是为了防止需要重新扩展堆,如果发生更多的大型分配。

在大多数平台上,Unity最终会将托管堆的空闲部分使用的内存释放回操作系统。这种情况发生的间隔不受保证,不可靠。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/100451.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频答题猜歌闯关娱乐微信小程序源码支持看视频答题闯关听歌猜歌答题流量主模式(团队奖励等)

功能强大UI美观的视频答题猜歌闯关娱乐微信小程序源码下载 后台管理资源本地化带数据和视频教程,这是一款拥有后端的闯关娱乐小程序。 支持个人小程序和企业小程序上线运营 功能强大齐全,带数据本地化 (数据在自己服务器自己管理无需担心第三方失效的问题) 支持看视…

【重拾C语言】七、指针(二)指针与数组(用指针标识数组、多维数组与指针、数组指针与指针数组)

目录 前言 七、指针 7.1~3 指针与变量、指针操作、指向指针的指针 7.4 指针与数组 7.4.1 用指针标识数组 7.4.2 应注意的问题 a. 数组名是指针常量 b. 指针变量的当前值 c. 数组超界 7.4.3 多维数组与指针 7.4.4 指针数组 a. 指针数组 b. 数组指针 c. 对比总结 前…

Reactor网络模式

文章目录 1. 关于Reactor模式的了解2. 基于Reactor模式实现epoll ET服务器2.1 EventItem类的实现2.2 Reactor类的实现Dispatcher函数AddEvent函数DelEvent函数EnableReadWrite函数 2.3 四个回调函数的实现acceptor回调函数recver回调函数sender回调函数errorer回调函数 3. epol…

突破封锁|华为芯片10年进化史:从K3V1到麒麟9000S

华为海思麒麟芯片过去10年研发历程回顾如下: 2009年:华为推出第一款手机芯片K3V1,采用65nm工艺制程,基于ARM11架构,主频600MHz,支持WCDMA/GSM双模网络。这款芯片搭载在华为U8800手机上,标志着华…

在SOLIDWORKS搭建一个简易的履带式机器人

文章目录 前言一、构建模型基本单元二、搭建车体模块三.插入轮子4.构建履带 前言 趁着十一假期,在solidworks中搭建了一个履带式机器人小车,计划将其应用在gazebo中完成多机器人编队的仿真。 一、构建模型基本单元 构建底板(a面&#xff09…

面试总结-Redis篇章(十二)——Redis是单线程的,为什么还那么快

Redis是单线程的,为什么还那么快 Redis是单线程的,为什么还那么快什么是IO多路复用 阻塞IO非阻塞IOIO多路复用 Redis是单线程的,为什么还那么快 Redis是纯内存操作,执行速度非常快采用单线程,避免不必要的上下文切换可…

Python中套接字实现服务端和客户端3-3

3 创建客户端的步骤 创建客户端的步骤如图5所示。 图5 创建客户端的步骤 从图5可以看出,对于客户端来说,首先创建套接字,之后通过创建的套接字去连接服务端,如果连接成功,则继续通过该套接字向服务端发送数据&#x…

【Mybatis源码】IDEA中Mybatis源码环境搭建

一、Mybatis源码源 在github中找到Mybatis源码地址:https://github.com/mybatis/mybatis-3 找到Mybatis git地址 二、IDEA导入Mybatis源码 点击Clone下载Mybatis源码 三、选择Mybatis分支 选择Mybatis分支,这里我选择的是3.4.x分支

【ChatGPT】无需代理使用ChatGPT

推荐一个无需代理、可以直接使用的、免费的、无需客户端的、稳定的ChatGPT终端 支持GPT-3.5和CPT-4 无需境外手机号 该工具比较稳定,断流情况很少 GPTDOS 注册地址:GPTDOS (使用我的邀请链接进行注册,双方都可以得到50000个toke…

Vue3 编译原理

文章目录 一、编译流程1. 解读入口文件 packgages/vue/index.ts2. compile函数的运行流程 二、AST 解析器1. ast 的生成2. 创建ast的根节点3. 解析子节点 parseChildren(关键)4. 解析模版元素 Element模版元素解析-举例分析 一、编译流程 1. 解读入口文…

嵌入式养成计划-33--数据库-sqlite3

七十一、 数据库 71.1 数据库基本概念 数据(Data) 能够输入计算机并能被计算机程序识别和处理的信息集合数据库 (Database)数据库是在数据库管理系统管理和控制之下,存放在存储介质上的数据集合 常用的数据库 大型数…

第二证券:5.5G时代将至 算力基建迎政策助力

昨日,A股全线低开,三大股指盘中均跌超1%,盘中冲高回落,午后逐渐止跌。到收盘,沪指跌0.44%报3096.92点,深成指微跌0.03%报10106.96点,创业板指跌0.26%报1998.61点,两市算计成交7700元…

【unity】制作一个角色的初始状态(左右跳二段跳)【2D横板动作游戏】

前言 hi~ 大家好!欢迎大家来到我的全新unity学习记录系列。现在我想在2d横板游戏中,实现一个角色的初始状态-闲置状态、移动状态、空中状态。并且是利用状态机进行实现的。 本系列是跟着视频教程走的,所写也是作者个人的学习记录笔记。如有错…

linux centos出现No space left on device解决方案

问题是因为系统磁盘空间不足 解决方法: 找到那个磁盘不足问题 df -lh 发现/dev/mapper/cl-root磁盘已用50G,有如下 解决方案: 1、如果是虚拟机可以通过分配空间使其空间增加 2、将其他不常用磁盘空间分配给cl-root如( /dev/mapper/cl-home &#…

unity 使用模拟器进行Profiler性能调试

这篇文章主要记录如何实现通过模拟器对打包的app游戏进行Profiler调试。主要记录一些比较重要的点。 准备工作 首先你要能够打包unity的安卓包,如果没有安装安卓组件,请先安装组件。 安装完成以后,会在unity的安装目录找到相应的SDK 这个…

嵌入式Linux裸机开发(五)中断管理

系列文章目录 文章目录 系列文章目录前言STM32 中断系统IMX6U中断控制8个中断GIC中断控制器GIC介绍中断IDGIC逻辑分块GIC协处理器 中断使能中断优先级 重点代码分析官方SDK函数start.S文件自行编写中断驱动文件 前言 最近在学习中发现,学Linux嵌入式不仅是对Linux的…

为Yolov7环境安装Cuba匹配的Pytorch

1. 查看Cuba版本 方法一 nvidia-smi 找到CUDA Version 方法二 Nvidia Control Panel > 系统信息 > 组件 > 2. 安装Cuba匹配版本的PyTorch https://pytorch.org/get-started/locally/这里使用conda安装 conda install pytorch torchvision torchaudio pytorch-cu…

JDK、JRE、JVM三者之间的关系

1.JDK 基本介绍 1) JDK 的全称 (Java Development Kit Java 开发工具包 ) JDK JRE java 的开发工具 [java, javac,javadoc,javap 等 ] 2) JDK 是提供给 Java 开发人员使用的,其中包含了 java 的开发工具,也包括了 JRE 。所以安装了 JDK ,就…

论文研读|Protecting Intellectual Property of Deep Neural Networks with Watermarking

目录 论文信息文章简介研究动机研究方法水印生成水印嵌入版权验证 实验结果有效性(Effectiveness)高效性(Converge Speed)保真度(Functionality)鲁棒性(Robustness)Anti-剪枝攻击&am…

SpringBoot源码分析-自动装配-实现原理

文章目录 SpringBoot自动装配前言介绍实现原理SpringBootApplicationEnableAutoConfigurationselectImports方法没有走?DeferredImportSelector源码分析设计目的 总结 SpringBoot自动装配 前言 什么是自动装配?用过Spring的应该都知道,虽然…