当前位置:网站首页>Rust 所有权进阶 -- 内存管理
Rust 所有权进阶 -- 内存管理
2022-06-27 17:58:00 【用户3147702】
1. 引言
此前的文章中,我们介绍了 Rust 的所有权:
所有权机制让 Rust 可以方便地实现内存的自动回收,但是 Rust 究竟是如何来划分和管理内存的呢?本文来介绍一下。
2. 内存的分配 -- 堆和栈
和很多其他语言一样,Rust 也将内存换分为堆和栈两个部分。由于 Rust 语言是一种系统级编程语言,我们在编写过程中是必须要清楚到底内存是被分配到堆空间还是栈空间的,不过通常,在栈中放置数据并不称为“分配”,而是“压入”。
在 Rust 中,只有在编译期已知且固定大小的数据会被分配在栈空间上,而那些编译期无法确定大小的数据,则只能被放置在堆空间中。
举个例子来说,Rust 中的字符串有两种类型:
// &str 类型
let str1 = "hello world!";
// String 类型
let str2 = String::from("hello");str1 是 &str 类型,它的值是大小固定且内容不可变的,他在编译期已经可以确定使用内存的大小,因此,str1 会被压到栈上。
str2 是 String 类型,这是一种 Rust 的封装类型,它是可变的字符串类型,例如,你可以通过下面的方法为 str2 添加新的内容:
str2.push_str(" world!");因此,String 类型的 str2 是被分配在堆空间的,尽管如此,实际上,在栈空间中仍然会压入一个结构,用来保存指向堆空间的指针、此次分配堆空间的容量,以及已使用长度。
3. 内存的释放
由于堆空间是在运行时动态分配的,所以和许多其他语言一样,堆空间的清理也是我们需要考虑的问题,Rust 的所有权机制很大程度上解决了这个问题。
当变量离开作用域时,根据所有权机制,Rust 会自动调用一个名为 drop 的特殊函数,在这个函数中,Rust 会释放所有不在被所有的内存。
此前的文章中,我们介绍了 Rust 的“移动”机制,简单的来说,就是对于基础类型,当把一个变量赋值给另一个变量时,Rust 会为新的变量在栈空间开辟一个新的空间,将原值复制一份,从而让两个变量在当前作用域内均为可用,这里说的“基础数据类型”只包括:
- 所有整数类型,包括有符号、无符号的类型,如 u32、i64 等;
- 布尔类型 bool;
- 字符类型 char。
而对于在堆空间中分配的数据来说,当把一个变量赋值给另一个变量时,Rust 会销毁原变量,数据的所有权被移动到了新的变量上。
这样的差别是为什么呢?假设保存着指向堆空间中数据的变量内容复制一份给新的变量,那么就会出现一个堆数据被两个指针指向的情况。当两个变量退出作用域时,Rust 就必须判断究竟要释放这个堆数据几次,并且在这样的情况下,修改一个变量就意味着另一个变量指向的实际数据发生了修改,行为仍然与基础类型不同。事实上,最好的解决办法是同步复制堆空间中的数据,也就是其他很多语言中的“深拷贝”,但这样一来性能势必受到极大地影响。因此,经过权衡,Rust 通过“移动”的策略来实现了堆空间变量的赋值。
边栏推荐
- What is ssr/ssg/isr? How do I host them on AWS?
- 308. 二维区域和检索 - 可变 线段树/哈希
- 1028 List Sorting
- 作用域-Number和String的常用Api(方法)
- Hanoi Tower problem
- Function key input experiment based on stm32f103zet6 Library
- 带你认识图数据库性能和场景测试利器LDBC SNB
- 实战回忆录:从Webshell开始突破边界
- Labelimg usage guide
- Vs code runs "yarn run dev" and reports "yarn": the file XXX cannot be loaded
猜你喜欢

GIS remote sensing R language learning see here

如何利用 RPA 实现自动化获客?

拥抱云原生:江苏移动订单中心实践

binder hwbinder vndbinder

基于STM32F103ZET6库函数按键输入实验

深度学习和神经网络的介绍

今晚战码先锋润和赛道第2期直播丨如何参与OpenHarmony代码贡献

Blink SQL内置函数大全

Function key input experiment based on stm32f103zet6 Library

The Fifth Discipline: the art and practice of learning organization
随机推荐
Error reported by Huada MCU Keil_ Weak's solution
基于STM32F103ZET6库函数蜂鸣器实验
Workflow automation low code is the key
你知道 log4j2 各项配置的全部含义吗?带你了解 log4j2 的全部组件
What is ssr/ssg/isr? How do I host them on AWS?
让单测变得如此简单 -- spock 框架初体验
Leetcode 1381. 设计一个支持增量操作的栈
labelimg使用指南
拥抱云原生:江苏移动订单中心实践
Oracle 获取月初、月末时间,获取上一月月初、月末时间
作用域-Number和String的常用Api(方法)
嵌入式软件开发中必备软件工具
C# 二维码生成、识别,去除白边、任意颜色
Is it safe to buy stocks online and open an account?
429-二叉树(108. 将有序数组转换为二叉搜索树、538. 把二叉搜索树转换为累加树、 106.从中序与后序遍历序列构造二叉树、235. 二叉搜索树的最近公共祖先)
shell脚本常用命令(四)
基于STM32F103ZET6库函数外部中断实验
“我让这个世界更酷”2022华清远见研发产品发布会圆满成功
中金证券经理给的开户二维码安全吗?找谁可以开户啊?
Embracing cloud Nativity: Practice of Jiangsu Mobile order center