编程语言各有各的“大能”,但如果谈到内存管理,Rust的话语权不是一般的高。GC(垃圾回收)?手动分配?对于掌握了Rust奥义的开发者而言,这些词汇简直弱爆了。
众所周知,Rust编程语言的主要卖点之一是它的内存安全性。Rust对待内存,非常有自己的个性。
与使用垃圾收集器的编程语言(如Haskell、Ruby和Python)不同,Rust为开发人员提供了快速功能,能够以一种独特的方式高效地使用和管理内存。
Rust通过使用借用检查器(borrow checker)、所有权(ownership)、借用(borrow)这三个概念来管理和确保跨堆栈和堆的内存安全来管理内存,从而实现内存管理。
本文讨论了Rust借用检查器,Rust与其他语言(如Go和C)的内存管理对比,以及Rust借用检查器的缺点。
PART 01
内存是如何工作的
在讨论Rust如何管理内存之前,先来回顾一下计算机内存是如何工作的。
分配给运行程序的计算机内存分为栈和堆。
栈是一种线性数据结构,它按顺序存储局部变量,而不用担心内存的分配和重新分配。每个线程都有自己的栈,当线程停止运行时,每个栈都会被释放。数据以后进先出(LIFO)的模式存储——新的数据堆积在旧数据的上面。
堆是一种分层数据结构,用于随机存储全局变量,内存分配和重新分配会是一个需要关注的问题。
当一个字面量被压入堆栈时,是会有一个确定的内存位置的;这使得分配和重新分配(入栈和出栈)很容易。但是,在堆上分配内存的随机过程会导致使用内存的开销很大,这使得重新分配内存的速度变慢,因为在堆上分配内存时会涉及到复杂的引用记录。
局部变量、函数和方法驻留在栈上,其他所有变量驻留在堆上;因为栈有固定的有限大小。
Rust通过在堆栈中存储字面量(整数、布尔值等)来有效地处理内存。像结构体和枚举这些类型的变量在编译时由于没有固定的大小,存储在堆中。
PART 02
所有权(ownership):“值”的主人
所有权是Rust中的一个概念,用来在没有垃圾收集器的情况下保证内存安全。Rust强制执行以下所有权规则:
-
每个值都有一个变量,称为owner(所有者)
-
每个值有且只有一个所有者
-
如果将变量赋值给新的所有者,那么原始值将被删除,否则它现在就会有两个所有者
在程序编译时,Rust编译器在程序编译之前会检