Unity值类型和引用类型

news2024/9/29 1:22:20

我们都知道C#编程语言中,数据类型被分为了两种:

  1. 值类型
  2. 引用类型

那么什么是值类型?什么是引用类型呢?它们的区别又是什么?

为了搞清楚这些问题,我们先列举一下我们开发中会碰到的值类型和引用类型。

  • 常见的值类型为:byte,short,int,long,float,double,decimal,char,bool 和 struct
  • 常见的引用类型为:class array interface delegate string System.Object dynamic

为了更清晰的对比值类型和引用类型,我们从内存的分配和回收两个角度来进行分析

内存分配

我们都知道,创建对象就需要有一块内存来承载相应的对象,我们也知道,在程序运行过程中内存会分为栈内存和堆内存,那么到底我们的值类型和引用类型的内存是分配在哪块内存上了呢?
要搞清楚这个问题首先我们先要了解值类型和堆内存,内存分配的差异:

  • 值类型只需要一段单独的内存,用于存储实际的数据

  • 引用类型需要存储两段内存

    • 第一段存储实际的数据。
    • 第二段存储的是一个引用,指向实际数据的存放位置。

    其实很多熟悉开发的小伙伴都口熟能详的知道一个概念,“值类型被存储在内存栈上,引用类型被存储在内存堆上”。这句话对不对呢。继续往下看…
    其实这句话呢,也对也不对,但要分使用场景

    数据不是其它类型的成员的情况下“值类型被存储在内存栈上,引用类型被存储在内存堆上”,大致如下图所示:
    在这里插入图片描述

但我们实际开发中很多时候类型都不是单独存在的,看下面的一段代码:

  public class ClassA{
    public int a;
    public string b;
  }

看到代码是不是感觉 a内存分配在内存栈,b内存分配在内存堆。很遗憾,实际情况是a和b都被分配在内存堆中。

那么哪个环节出现问题了呢?
因为a是ClassA的成员属性,而ClassA是一个引用类型,所以ClassA的数据部分是被存储在内存堆上的,大致如下图所示:
在这里插入图片描述

总结:

引用类型的数据一定是被分配在内存堆上的,而引用类型的引用以及值类型的数据却并不一定分配在内存栈上。

  1. 局部变量:

引用类型的引用和值类型的数据分配在内存栈上

  1. 公共变量

引用类型的引用和值类型的数据的分配根承载它的对象所在的内存有关,如果承载它的对象在堆内存中那么它就跟着被分在堆内存中,如果承载它的对象被分配在栈内存中那么它就跟着被分在栈内存中。

内存回收

在说回收之前我们需要先了解一下栈内存和堆内存的定义和结构如下:

栈内存

栈是一个内存数组,是一个LIFO(last-in first-out,后进先出)的数据结构。栈存储几种类型的数据:某些类型变量的值、程序当前的执行环境、传递给方法的参数。

栈的特点:(1)数据只能从栈的顶端插入和删除。(2)把数据放到栈顶称为入栈。(3)从栈顶删除数据称为出栈。(4)内存连续 (5)内存自行维护

堆内存

堆是一块内存区域,在堆里可以分配大块的内存用于存储某种类型的数据对象。与栈不同,堆里的内存能够以任意顺序存入和移除。
堆的特点: (1)内存无序。 (2)内存不可自行维护需要借助CLR的GC机制

由于栈内存的内存连续性以及内存的自行维护,所以栈内存的申请和释放相对于堆内存要快。
而堆内存的内存回收完全借助于CLR的GC机制,什么时候回收几乎是不可控的,且由于堆内存的不连续性的特点,在GC之后容易产生内存碎片,从而造成内存浪费。

什么时候触发GC?

  1. 在堆内存上进行内存分配操作时,内存不够的时候会触发GC
  2. 自动触发,Unity会不定时的自动触发GC
  3. 代码强制执行

GC是怎样工作的?

  1. 挂起所有正在运行的线程
  2. 检查堆内存上的每个对象
  3. 搜索对象的所有引用
  4. 没有被引用的对象都是垃圾,被标记为可删除
  5. 遍历删除所有被标记的对象,释放内存

看到GC的工作机制你就会知道一次GC是多么的困难,并且随着我们的程序复杂性的提高,占用的CPU算力也会越高就会造成程序卡顿,所以在项目开发过程中我们一定要想办法减少GC,或选择在合适的位置进行GC

怎么减少GC?

  1. 对象池
  2. stringbuilder的使用
  3. 减少装箱操作
  4. 避免频繁的调用协程,每一次StartCoroutine()实际上是new一个新的对象
  5. 用for代替foreach foreach会在堆上产生一个system.object

最后我们简单用一个示例图来模拟一下一个引用类型的申请:

在这里插入图片描述

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

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

相关文章

Canvas绘制图片和区域(前端使用Canvas绘制图片,并在图片上绘制区域)

简介&#xff1a;在Web开发中&#xff0c;有时候我们需要在图片上进行一些交互式操作&#xff0c;比如绘制区域、标记等。这种场景下&#xff0c;我们可以使用HTML5的<canvas>元素来实现。Canvas 是 HTML5 提供的一种图形绘制接口&#xff0c;可以通过 JavaScript 在网页…

AI应用案例:供应链平台健康状况和发展趋势分析

某供应链平台在2019年就遍布了中国320个城市&#xff0c;为2600多家企业提供超40万个品类的供应链服务。它是通过直供城市终端销售门店&#xff0c;甚至是消费者&#xff0c;最大限度保证品牌和终端的销售利益。 但是平台交易市值较大、涉及的行业较多&#xff0c;而且打破了传…

linux grep命令搜索指定路径

在Linux开发的过程中grep这个搜索命令&#xff0c;是必不可少的存在。它可以快速的搜索出来我们需要的关键字所在的位置。 有助于我们快速分析定位问题。 下面&#xff0c;分享一个简单实用的小技巧。 原始grep 最终grep grep过滤掉二进制的文件 -I选项 结论 这样子是不…

队列的实现(使用C语言)

完整代码链接&#xff1a;DataStructure: 基本数据结构的实现。 (gitee.com) 目录 一、队列的概念&#xff1a; 二、队列的实现&#xff1a; 使用链表实现队列&#xff1a; 1.结构体设计&#xff1a; 2.初始化&#xff1a; 3.销毁&#xff1a; 4.入队&#xff1a; 5.…

深入了解 Flask Request

文章目录 获取请求数据获取请求信息文件上传总结 Flask 是一个轻量级的 Python Web 框架&#xff0c;其简洁的设计和灵活的扩展性使其成为了许多开发者的首选。在 Flask 中&#xff0c;处理 HTTP 请求是至关重要的&#xff0c;而 Flask 提供了丰富而强大的 request 对象来处理…

【Linux网络编程】I/O多路转接之select

select 1.初识select2.了解select基本概念和接口介绍3.select服务器4.select特点及优缺点总结 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一起努力吧!&#x1f603;&#x1f603;…

企业微信主体能不能修改?

企业微信变更主体有什么作用&#xff1f;当我们的企业因为各种原因需要注销或已经注销&#xff0c;或者运营变更等情况&#xff0c;企业微信无法继续使用原主体继续使用时&#xff0c;可以申请企业主体变更&#xff0c;变更为新的主体。企业微信变更主体的条件有哪些&#xff1…

ansible——INVENTORY主机清单

一、Inventory主机清单 Inventory支持对主机进行分组&#xff0c;每个组内可以定义多个主机&#xff0c;每个主机都可以定义在任何一个或多个主机组内 二、Inventory主机清单部署 2.1 前期准备 systemctl stop firewalld setenforce 0 yum install epel-release -y yum install…

Panasonic机器人维修|松下机械手维修过程

在我们的科技日新月异的今天&#xff0c;松下机器人已经广泛应用于各个领域&#xff0c;发挥着越来越重要的作用。然而&#xff0c;这些Panasonic机械手维修过程也是一项重要且复杂的工作。 一、准备工作 在进行松下机器人维修前&#xff0c;需要充分了解机器人的构造和工作原理…

JavaScript逆向技术

JavaScript逆向之旅&#xff1a;深入解析与实践 在数字时代&#xff0c;前端技术的迅速发展使得Web应用变得更加丰富和复杂。JavaScript&#xff0c;作为前端的核心语言&#xff0c;其安全性和隐私保护问题也逐渐浮出水面。JavaScript逆向&#xff0c;作为一种从前端代码中提取…

2022 年全国职业院校技能大赛高职组云计算赛项试卷(容器云)

#需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包…

高效工作之软件系统——数据结构登记表

数据结构模板 开发完软件系统后&#xff0c;往往需要进行一些登记——《软件系统数据结构登记表》 然后软件项目有60个表左右&#xff0c;难道需要手动录入&#xff0c;那肯定不可能 工欲善其事必先利其器&#xff01;go。。。同事给的模板是下图 效果图 于是想到 之前使用…

C++学习第三十一课:C++ 线程与多线程编程的应用

一、线程与多线程编程的基本概念 线程的定义 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流&#xff0c;一个进程中可以并发多个线程&#xff0c;每条线程并行执行不同的任务…

《机器学习by周志华》学习笔记-决策树-01

本书中的「决策树」有时指学习方法,有时指学得的树。 1、基本流程 1.1、概念 基本流程,亦称「判定树」 决策树(decision tree),是一种常见的机器学习方法。以二分类任务为例,我们希望从给定训练数据集学得一个模型,用以对新样例进行分离。 以二分类任务为例,可看作对…

揭秘微服务架构:十大设计模式助力企业数字化转型

微服务架构中10个常用的设计模式 微服务是一种架构风格&#xff0c;它将一个复杂的应用拆分成多个独立自治的服务&#xff0c;每个服务负责应用程序中的一小部分功能。这些服务通过定义良好的API进行通信&#xff0c;通常是HTTP RESTful API或事件流。微服务架构的主要特点包括…

深入学习指针3

目录 前言 1.二级指针 2.指针数组 3.指针数组模拟二维数组 前言 Hello,小伙伴们我又来了&#xff0c;上期我们讲到了数组名的理解&#xff0c;指针与数组的关系等知识&#xff0c;那今天我们就继续深入到学习指针域数组的练联系&#xff0c;如果喜欢作者菌生产的内容还望不…

攻略:大学生三下乡投稿媒体网站和快速方法

作为当代大学生,不仅需要学习和掌握知识,更需要将所学知识运用到实践中,参与各种社会实践活动。其中,“三下乡”活动就是一个非常有意义的社会实践活动。三下乡社会实践活动新闻稿投稿网站有哪些?有哪些方式可以快速投稿呢&#xff1f;今天小编给大家一次讲个明白。 三下乡新…

C 语言中怎么产生真正的随机数?

在C语言中&#xff0c;要产生真正的随机数&#xff0c;我们通常使用标准库中的 <stdlib.h> 头文件中提供的随机数生成函数。 这些函数可以生成伪随机数&#xff0c;但它们在一定程度上是随机的&#xff0c;足以满足大多数应用程序的需求。 1. 伪随机数生成函数 C标准库…

【从零开始学架构 架构基础】架构设计的本质、历史背景和目的

本文是《从零开始学架构》的第一篇学习笔记&#xff0c;主要理解架构的设计的本质定义、历史背景以及目的。 架构设计的本质 分别从三组概念的区别来理解架构设计。 系统与子系统 什么是系统&#xff0c;系统泛指由一群有关联的个体组成&#xff0c;根据某种规则运作&#…

Java实现的网上书店系统(附带完整源码)

作者声明:文章仅供学习交流与参考!严禁用于任何商业与非法用途!否则由此产生的一切后果均与作者 实现技术:JSP技术;javaBean;servlet;MySql数据库。 系统功能结构图 该系统为MVC结构,它的运行环境分客户端、应用服务器端和数据库服务器端三部分 书店系统需求分析: 通过…