【Rust自学】4.1. 所有权:栈内存 vs. 堆内存

news2024/12/23 20:54:25

4.1.0 写在正文之前

在学习了Rust的通用编程概念后,就来到了整个Rust的重中之重——所有权,它跟其他语言都不太一样,很多初学者觉得学起来很难。这个章节就旨在让初学者能够完全掌握这个特性。

本章有三小节:

  • 所有权:栈内存 vs. 堆内存(本文)
  • 所有权规则、内存与分配
  • 所有权与函数

喜欢的话记得点赞、收藏加关注哦,想要跟着学下去记得关注专栏哦

4.1.1. 什么是所有权

所有权是Rust最独特的特性,它让Rust无需GC(垃圾收集器)就可以保证内存安全。

所有程序在运行时都必须管理它们使用计算机内存的方式。有的语言依靠垃圾收集机制,在程序运行时,它们会不断寻找不在使用的内存(比如C#);在其他语言中,程序员必须显式地分配和释放内存(比如C/C++)。

Rust不同于前两种。Rust使用所有权系统来管理内存,这个系统里还有一套规则,而编译器在编译时就会检查这套规则,而且这种做法不会产生任何的运行时开销。也就是说,在程序运行时,这种所有权特性不会减慢程序运行的速度,因为Rust把内存管理相关工作都提前到了编译时。

4.1.2. 栈内存(Stack) vs. 堆内存(Heap)

一般来说,程序员不会经常考虑栈内存与堆内存之间的区别。对于Rust这样的系统级编程语言来说,一个值它是在栈内存上还是在堆内存上对语言的行为和你要做的某些决定是由更大影响的。

在代码运行时,栈内存和堆内存都是可用的内存,但他们的结构很不相同。

4.1.3. 存储数据

1. 栈内存

栈内存按值的接收顺序来存储,按相反的顺序来将他们移除(后进先出,Last In First Out,简写为LIFO)。

添加数据叫压入栈(压栈),移除数据叫弹出栈(出栈)。

所有存储在栈内存上的数据必须拥有已知的固定的大小。 相反的,编译时大小未知的数据或是运行时大小可能发生变化的数据必须存放在堆内存上。

2. 堆内存

堆内存的的内存组织性差一些。当把数据放入堆内存时,会请求一定的空间。操作系统会在堆内存中找到一块足够大的空间,把它标记为在用,并返回一个指针,也就是这个空间的地址。这个过程叫做在Heap上进行内存分配,有时简称为"分配"。

3. 指针与内存

因为指针是固定大小的,可以把指针放在栈内存上。但如果想要指针所指向的具体数据时,就必须得使用指针所指向的地址来访问它。、

把数据压到栈内存上比在堆内存上分配要快得多

  • 在栈内存上,操作系统不需要寻找用来存储新数据的空间,那个位置永远都在栈内存的顶端(栈内存的末尾位置,也就是当前可用的栈内存的起始位置)。

  • 在堆内存上分配空间则需要做更多的工作:操作系统首先需要找到一个足够大的空间来存放数据,然后要做好记录方便下一次的分配。

4.1.4. 访问数据

访问栈内存中的数据要比访问堆内存中的数据快,因为需要通过指针才能找到堆内存中的数据,多了指针跳转这么一个环节,它属于间接的访问。而对于现代的处理器来说,由于缓存的缘故,如果指令在内存中跳转的数据越少,那么速度就越快。

如果数据存放的距离比较近,那么处理器的处理速度就会更快一些,例如放在栈内存上;反之,如果数据之间距离较远,那么处理速度就会慢一些,例如放在堆内存上(在堆内存上分配大量的空间也是需要时间的)。

4.1.5. 函数调用

当代码调用函数时,值被传入函数(也包括指向堆内存的指针)。函数本地的变量被压在栈内存上。当函数结束后,这些值会从栈内存上弹出。

4.1.6. 所有权存在的原因

所有权解决的问题:

  • 跟踪代码中分配的堆内存空间,换句话说就是跟踪代码的哪些部分正在使用堆内存的哪些数据
  • 最小化堆内存上的重复数据量
  • 清理堆内存上未使用的数据以避免空间不足

一旦懂了所有权,就不用经常地去想堆内存和栈内存了。但是知道管理堆内存数据是所有权存在的原因有助于解释它为什么会这样工作。

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

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

相关文章

redis开发与运维-redis02-redis数据类型与命令总结

文章目录 【README】【1】redis通用命令与数据结构【1.1】通用命令【1.2】数据结构与内部编码【1.3】redis单线程架构【1.3.1】redis单线程优缺点 【2】字符串(值的类型为字符串)【2.1】常用命令【2.1.1】设置值【2.1.2】获取值【2.1.3】批量设置值【2.1…

机器学习《西瓜书》学习笔记《待续》

如果说,计算机科学是研究关于“算法”的学问,那么机器学习就是研究关于“学习算法”的学问。 目录 绪论引言基本术语 扩展向量的张成-span使用Markdown语法编写数学公式希腊字母的LaTex语法插入一些数学的结构插入定界符插入一些可变大小的符号插入一些函…

电脑开机提示error loading operating system怎么修复?

前一天电脑还能正常运行,但今天启动时却显示“Error loading operating system”(加载操作系统错误)。我已经仔细检查了硬盘、接线、内存、CPU和电源,确认这些硬件都没有问题。硬盘在其他电脑上可以正常使用,说明不是硬…

git企业开发的相关理论(一)

目录 一.初识git 二.git的安装 三.初始化/创建本地仓库 四.配置用户设置/配置本地仓库 五.认识工作区、暂存区、版本库 六.添加文件__场景一 七.查看 .git 文件/添加到本地仓库后.git中发生的变化 1.执行git add后的变化 index文件(暂存区) lo…

Linux网络——网络基础

Linux网络——网络基础 文章目录 Linux网络——网络基础一、计算机网络的发展背景1、网络的定义(1) 独立模式(2)网络互联 2、局域网 LAN3、广域网 WAN4、比较局域网和广域网5、扩展 —— 域域网和互联网 二、协议1、协议的概念2、…

react中实现导出excel文件

react中实现导出excel文件 一、安装依赖二、实现导出功能三、自定义列标题四、设置列宽度五、样式优化1、安装扩展库2、设置样式3、扩展样式功能 在 React 项目中实现点击按钮后导出数据为 Excel 文件,可以使用 xlsx 和 file-saver 这两个库。 一、安装依赖 在项目…

7-Zip 加密功能使用教程:如何设置密码保护压缩文件

压缩包如何加密?7-Zip 是一款开源的文件归档工具,支持多种压缩格式,并提供了对压缩文件进行加密的功能。使用 7-Zip 可以轻松创建和解压 .7z、.zip 等格式的压缩文件,并且可以通过设置密码来保护压缩包中的数据不被未授权访问。 准…

[计算机网络]ARP协议的故事:小明找小红的奇妙旅程

1.ARP小故事 在一个繁忙的网络世界中,每个设备都有自己的身份标识——MAC地址,就像每个人的身份证号码一样。在这个故事里,我们的主角小明(主机)需要找到小红(目标主机)的MAC地址,才…

新版国标GB28181设备端Android版EasyGBD支持国标GB28181-2022,支持语音对讲,支持位置上报,开源在Github

经过近3个月的迭代开发,新版本的国标GB28181设备端EasyGBD安卓Android版终于在昨天发布到Github了,最新的EasyGBD支持了国标GB28181-2022版,还支持了语音对讲、位置上报、本地录像等功能,比原有GB28181-2016版的EasyGBD更加高效、…

McDonald‘s Event-Driven Architecture 麦当劳事件驱动架构

原文链接 1 mcdonalds-technical-blog/ 原文链接 2 mcdonalds-technical-blog/ 麦当劳在异步、事务性和分析性处理用例中使用跨技术栈的事件,包括移动订单进度跟踪和向客户发送营销通信(交易和促销)。 统一事件平台(unified eve…

【CSS in Depth 2 精译_089】15.2:CSS 过渡特效中的定时函数

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第五部分 添加动效 ✔️【第 15 章 过渡】 ✔️ 15.1 状态间的由此及彼15.2 定时函数 ✔️ 15.2.1 定制贝塞尔曲线 ✔️15.2.2 阶跃 ✔️ 15.3 非动画属性 文章目录 15.2 定时函数 Timing function…

一个开源的自托管虚拟浏览器项目,支持在安全、私密的环境中使用浏览器

大家好,今天给大家分享一个开源的自托管虚拟浏览器项目Neko,旨在利用 WebRTC 技术在 Docker 容器中运行虚拟浏览器,为用户提供安全、私密且多功能的浏览体验。 项目介绍 Neko利用 WebRTC 技术在 Docker 容器中运行虚拟浏览器,提供…

AW36518芯片手册解读(3)

接前一篇文章:AW36518芯片手册解读(2) 二、详述 3. 功能描述 (1)上电复位 当电源电压VIN降至预定义电压VPOR(典型值为2.0V)以下时,该设备会产生复位信号以执行上电复位操作&#x…

浅谈目前我开发的前端项目用到的设计模式

浅谈目前我开发的前端项目用到的设计模式 前言 设计模式很多,看到一个需求,项目,我们去开发的时候,肯定是做一个整体的设计进行开发,而在这次我项目中,我也做了一个整体的设计,为什么要设计&a…

线性规划中的几种逻辑表达式

线性规划中的几种逻辑表达式 注意: 摘录字刘博士的《数学建模与数学规划》, 以便用时可查。 实际上Gurobi API 中自身放啊变的逻辑表达式函数,下面列出自定义的实现方式。 1 逻辑与 如果 x 1 1 x_1 1 x1​1, x 2 1 x_2 1 x2​1, 那…

JVM对象分配内存如何保证线程安全?

大家好,我是锋哥。今天分享关于【JVM对象分配内存如何保证线程安全?】面试题。希望对大家有帮助; JVM对象分配内存如何保证线程安全? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在JVM中,对象的内存分配…

Antd react上传图片格式限制

限制分辨率&#xff08;像素&#xff09; <a-upload :before-upload"beforeUpload">// 上传图片宽高比例限制const beforeUpload file > {return new Promise((resolve, reject) > {// // 图片类型限制// let isJpgOrPng file.type image/png || fil…

基于 iAP2 协议 的指令协议,用于对安防设备的 MCU 进行操作

协议设计目标 1. 安全性&#xff1a;通过 iAP2 协议与 MCU 设备进行安全通信。 2. 通用性&#xff1a;支持对安防设备的常见功能进行操作&#xff0c;如状态查询、设备控制、参数配置等。 3. 高效性&#xff1a;数据结构简洁清晰&#xff0c;易于解析和扩展。 4. 扩展性&#x…

Type-C单口便携屏LDR6021

随着科技的飞速发展&#xff0c;便携式电子产品在我们的日常生活中扮演着越来越重要的角色。在这一背景下&#xff0c;Type-C单口便携显示器作为一种新兴的显示设备&#xff0c;凭借其独特的优势迅速崭露头角&#xff0c;成为市场的新宠。本文将深入探讨Type-C单口便携显示器的…

Ubuntu 20.04 卸载和安装 MySQL8.0

卸载 首先&#xff0c;检查一下系统安装的软件包有哪些&#xff0c;使用dpkg -l | grep mysql命令&#xff1a; 为了将MySQL卸载干净&#xff0c;这些文件都需要被删除。 在Ubuntu20.04系统下&#xff0c;卸载干净MySQL8.0以确保下一次安装不会出错&#xff0c;可以按照以下…