首页 > 系统相关 >【Rust自学】4.1. 所有权:栈内存 vs. 堆内存

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

时间:2024-12-19 12:31:03浏览次数:6  
标签:4.1 vs 内存 所有权 数据 Rust 指针

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. 所有权存在的原因

所有权解决的问题:

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

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

标签:4.1,vs,内存,所有权,数据,Rust,指针
From: https://blog.csdn.net/weixin_71793197/article/details/144574956

相关文章

  • MacOS+vscode调试mysql8.0源码
    环境:MacOsM1vscode前置:安装brew##安装brew/usr/bin/ruby-e"$(curl-fsSLhttps://cdn.jsdelivr.net/gh/ineo6/homebrew-install/install)"##环境变量eval"$(/opt/homebrew/bin/brewshellenv)"下载源码带boost版本下载之后解压vscode插件安装##直接搜索,然后安......
  • 明察秋毫--用ss工具统计网络栈内存使用
    前言本文介绍了用ss工具来统计一下当前网络栈的内存使用情况环境准备组件版本操作系统Ubuntu22.04.4LTS查看socket内存相关参数,-m参数▶ss-tmStateRecv-QSend-QLocalAddres......
  • Linux内存泄露案例分析和内存管理分享
    作者:京东科技李遵举一、问题近期我们运维同事接到线上LB(负载均衡)服务内存报警,运维同事反馈说LB集群有部分机器的内存使用率超过80%,有的甚至超过90%,而且内存使用率还再不停的增长。接到内存报警的消息,让整个团队都比较紧张,我们团队负责的LB服务是零售、物流、科技等业务服务的流......
  • 获取任意一个进程的共享内存的fd对应的资源,增加引用,实现数据的接管——包含非export的
    一、背景在之前的 memfd配合跨进程传输fd的例子及原理-CSDN博客博客里,我们讲了跨进程通过socket传递fd的底层实现原理,并且给了一个例子来替代socket传输和转换部分的逻辑,直接使用底层fd和file的接口来通过模块ko来实现跨进程的fd的转换和重新映射。这篇博客里,我们继续fd的......
  • 2024.12.18做题,对AI的提问记录,拓扑排序和图的关键活动
    什么是拓扑排序拓扑排序(TopologicalSorting)是一种用于有向无环图(DAG,DirectedAcyclicGraph)的线性排序。对于图中的每一个有向边u->v,顶点u在排序中都出现在顶点v之前。拓扑排序可以用于解决依赖关系的问题,例如任务调度、编译顺序等。拓扑排序的常见算法有两种:Kahn's......
  • VSFTPD 服务加固
    (1)设置数据连接的超时时间为2分钟、无任何操作的超时时间为5分钟。Vi/etc/vsftpd.confdata_connection_timeout=120idle_session_timeout=300修改后重启vsftpd生效sudosystemctlrestartvsftpd设置站点本地用户访问的最大传输速率为1M。    Vi/etc/vsftpd.conf......
  • “上四休三”VS“混合模式”办公,如何安排工作时间实现高效办公
    前言最近日本东京颁布了“上四休三”的工作制,2025年4月开始启动。日本东京都政府将允许其员工每周工作4天,以扭转日本的低出生率。此制度规定只要雇员在4周内累计的工作时长达到155个小时,就可以自由安排休息时间。比如在周一至周四每天工作约为9.7小时,则可以选择在周五休息。......
  • docker配置国内镜像2024.11.18更新
    根据最新的搜索结果,以下是一些国内可用的Docker镜像源配置,你可以按照以下步骤进行配置:创建或修改Docker配置文件:在Linux系统中,你需要修改或创建/etc/docker/daemon.json文件。如果文件不存在,你可以使用以下命令创建它:sudomkdir-p/etc/dockersudotee/etc/docker/daemon......
  • 代码危机:“内存溢出” 事件的深度剖析与反思
    在我初入编程世界的时候,曾天真地以为只要逻辑严谨,代码就会如预期般顺畅运行。然而,一个名为“内存溢出”的恶魔,给我上了刻骨铭心的一课。电商平台订单系统:危机初现        当时我所在的团队正在全力开发一款大型电商平台的订单处理系统。这个系统需要处理海量的订单......
  • Vue - 萤石云监控 ezuikit 视频实例销毁方案,解决使用stop方法无法销毁EZUIKit实例或销
    前言这方面教程很少,本文提供详细解决方案。在vue2|vue3项目开发中,项目集成对接萤石监控摄像头如何销毁EZUIKit实例教程,解决页面存在多个实时监控画面视频情况下,关闭某一个监控依然有声音和占用浏览器内存问题,另外如果要管理的摄像头监控播放器很多会导致分页情况下......