当前位置:网站首页>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 通过“移动”的策略来实现了堆空间变量的赋值。
边栏推荐
- 华大单片机KEIL添加ST-LINK解决方法
- 现在网上买股票开户身份证信息安全吗?
- CDGA|交通行业做好数字化转型的核心是什么?
- Bit. Store: long bear market, stable stacking products may become the main theme
- Where to look at high-yield bank financial products?
- OpenSSL client programming: SSL session failure caused by an obscure function
- Redis 原理 - String
- 金鱼哥RHCA回忆录:DO447管理项目和开展作业--创建作业模板并启动作业
- Bit.Store:熊市漫漫,稳定Staking产品或成主旋律
- Pyhton爬取百度文库文字写入word文档
猜你喜欢

OpenSSL client programming: SSL session failure caused by an obscure function

Bit. Store: long bear market, stable stacking products may become the main theme

基于STM32F103ZET6库函数外部中断实验

工作流自动化 低代码是关键

在线文本按行批量反转工具

The Fifth Discipline: the art and practice of learning organization

UE4实现长按功能

基于STM32F103ZET6库函数跑马灯实验

Embracing cloud Nativity: Practice of Jiangsu Mobile order center

Redis 原理 - String
随机推荐
Making single test so simple -- initial experience of Spock framework
(LC)46. 全排列
数仓的字符截取三胞胎:substrb、substr、substring
Determine whether a variable is an array or an object?
深度学习和神经网络的介绍
Code and principle of RANSAC
Function key input experiment based on stm32f103zet6 Library
1023 Have Fun with Numbers
【建议收藏】ABAP随笔-EXCEL-4-批量导入-推荐
指针和结构体
如何利用 RPA 实现自动化获客?
图扑数字孪生智慧能源一体化管控平台
判断一个变量是数组还是对象?
shell脚本常用命令(四)
Memoirs of actual combat: breaking the border from webshell
形参的默认值-及return的注意事项-及this的使用-和箭头函数的知识
# Leetcode 821. 字符的最短距离(简单)
1027 Colors in Mars
Cucumber自动化测试框架使用
Tupu digital twin intelligent energy integrated management and control platform