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

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.rhkb.cn/news/492768.html

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

相关文章

LabVIEW与PLC点位控制及OPC通讯

在工业自动化中,PLC通过标准协议(如Modbus、Ethernet/IP等)与OPC Server进行数据交换,LabVIEW作为上位机通过OPC客户端读取PLC的数据并进行监控、控制与处理。通过这种方式,LabVIEW能够实现与PLC的实时通信&#xff0c…

C++ OpenGL学习笔记(1、Hello World空窗口程序)

终于抽出时间系统学习OpenGL 教程,同时也一步一步记录怎样利用openGL进行加速计算。 目录 1、环境准备1.1、库的下载1.2、库的选择及安装 2、OpenGL第一个项目,Hello World!2.1、新建hello world控制台项目2.2、配置openGL环境2.2.1 包含目录配置2.2.2 …

系统移植——Linux 内核顶层 Makefile 详解

一、概述 Linux Kernel网上下载的版本很多NXP等有自己对应的版本。需要从网上直接下载就可以。 二、Linux内核初次编译 编译内核之前需要先在 ubuntu 上安装 lzop 库 sudo apt-get install lzop 在 Ubuntu 中 新 建 名 为 “ alientek_linux ” 的 文 件夹 , …

ubuntu16.04ros-用海龟机器人仿真循线系统

下载安装sudo apt-get install ros-kinetic-turtlebot ros-kinetic-turtlebot-apps ros-kinetic-turtlebot-interactions ros-kinetic-turtlebot-simulator ros-kinetic-kobuki-ftdi sudo apt-get install ros-kinetic-rocon-*echo "source /opt/ros/kinetic/setup.bash…

Connection lease request time out 问题分析

Connection lease request time out 问题分析 问题背景 使用apache的HttpClient,我们知道可以通过setConnectionRequestTimeout()配置从连接池获取链接的超时时间,而Connection lease request time out正是从连接池获取链接超时的报错,这通常…

【文档搜索引擎】在内存中构造出索引结构(上)

文章目录 主要思路正排索引和倒排索引的表示1. 正排索引查询文档详细信息2. 倒排索引中查找关联词3. 新增文档正排索引倒排索引实现词频统计 主要思路 通过 Index 类,在内存中构造出索引结构。这个类要提供的方法: 给定一个 docId,在正排索…

单节点calico性能优化

在单节点上部署calicov3273后,发现资源占用 修改calico以下配置是资源消耗降低 1、因为是单节点,没有跨节点pod网段组网需要,禁用overlay方式网络(ipip,vxlan),使用route方式网络 配置calico-node的环境变量 CALICO_IPV4POOL_I…

tryhackme-Pre Security-HTTP in Detail(HTTP的详细内容)

任务一:What is HTTP(S)?(什么是http(s)) 1.What is HTTP? (HyperText Transfer Protocol)(什么是 HTTP?(超文本传输协议)) http是你查看网站的时候遵循的…

Javascript面试手撕常见题目(回顾一)

1.JS查找文章中出现频率最高的单词? 要在JavaScript中查找文章中出现频率最高的单词,你可以按照以下步骤进行操作: 将文章转换为小写:这可以确保单词的比较是大小写不敏感的。移除标点符号:标点符号会干扰单词的计数。将文章拆…

算法-Z-order算法

1、学习背景 激光雷达点云是无序的,Transformer只能对有序的数据进行处理,为了将Transformer用在点云处理中,需要将无序的点云转换成有序的数据,另外,由于Transformer会用到局部注意力机制,所以将无序的数据…

ElasticSearch 数据聚合与运算

1、数据聚合 聚合(aggregations)可以让我们极其方便的实现数据的统计、分析和运算。实现这些统计功能的比数据库的 SQL 要方便的多,而且查询速度非常快,可以实现近实时搜索效果。 注意: 参加聚合的字段必须是 keywor…

三、使用langchain搭建RAG:金融问答机器人--检索增强生成

经过前面2节数据准备后,现在来构建检索 加载向量数据库 from langchain.vectorstores import Chroma from langchain_huggingface import HuggingFaceEmbeddings import os# 定义 Embeddings embeddings HuggingFaceEmbeddings(model_name"m3e-base")#…

SSH连接成功,但VSCode连接不成功

环境 在实验室PC上连接服务器234 解决方案:在VSCode中重新添加远程主机 删除旧的VSCode Server 在远程主机上,VSCode会安装一个‘vscode-server’服务来支持远程开发,有时旧的‘vscode-server’文件可能会导致问题,删除旧的&am…

scala中正则表达式的使用

正则表达式: 基本概念 在 Scala 中,正则表达式是用于处理文本模式匹配的强大工具。它通过java.util.regex.Pattern和java.util.regex.Matcher这两个 Java 类来实现(因为 Scala 运行在 Java 虚拟机上,可以无缝使用 Java 类库&…

COMSOL with Matlab

文章目录 基本介绍COMSOL with MatlabCOMSOL主Matlab辅Matlab为主Comsol为辅 操作步骤常用指令mphopenmphgeommghmeshmphmeshstatsmphnavigatormphplot常用指令mphsavemphlaunchModelUtil.clear 实例教学自动另存新档**把语法套用到边界条件**把语法套用到另存新档 函数及其微分…

小鹏“飞行汽车”上海首飞,如何保障智能出行的安全性?

近日,小鹏汇天的“陆地航母”飞行汽车在上海陆家嘴成功完成首飞,标志着飞行汽车时代在中国正式拉开序幕。作为一项突破性的科技创新,飞行汽车不仅将重塑我们的出行方式,还将深刻改变城市的交通格局。此次飞行不仅证明了飞行汽车的…

Service Discovery in Microservices 客户端/服务端服务发现

原文链接 Client Side Service Discovery in Microservices - GeeksforGeeks 原文链接 Server Side Service Discovery in Microservices - GeeksforGeeks 目录 服务发现介绍 Server-Side 服务发现 实例: Client-Side 服务发现 实例: 服务发现介绍…

概率论得学习和整理27:关于离散的数组 随机变量数组的均值,方差的求法3种公式,思考和细节。

目录 1 例子1:最典型的,最简单的数组的均值,方差的求法 2 例子1的问题:例子1只是1个特例,而不是普遍情况。 2.1 例子1各种默认假设,导致了求均值和方差的特殊性,特别简单。 2.2 我觉得 加权…

深度学习之超分辨率算法——SRGAN

更新版本 实现了生成对抗网络在超分辨率上的使用 更新了损失函数,增加先验函数 SRresnet实现 import torch import torchvision from torch import nnclass ConvBlock(nn.Module):def __init__(self, kernel_size3, stride1, n_inchannels64):super(ConvBlock…

基于微信小程序的短视频系统(SpringBoot)+文档

💗博主介绍💗:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示:文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…