铁锈有什么,而不是垃圾收集器?

一个基本的问题,但我是新的Rust / C / C + +等。我知道Rust没有垃圾收集器,我想知道当一个绑定超出范围时如何释放内存。

所以在这个例子中,我知道Rust退回给分配给'a'的内存当它超出范围。

{ let a = 4 } 

我遇到的这个问题首先是如何发生的,其次,这不是一种垃圾收集? 它与“典型”垃圾收集有什么不同?

道歉,我知道这有点基本,但我来自dynamic语言。

垃圾收集通常是周期性地或按需要使用,就像堆已经接近满或高于某个阈值一样。 然后根据algorithm查找未使用的variables并释放它们的内存。

Rust会知道variables何时超出范围,或者在编译时终止它的生命周期,从而插入相应的LLVM /汇编指令来释放内存。

Rust也允许某种垃圾收集,比如primefaces引用计数 。

pipe理程序中的资源(包括内存)的基本思想,不pipe是什么策略,都是可以回收与无法访问的“对象”有关的资源。 除了内存,这些资源可以是互斥锁,文件句柄,套接字,数据库连接…

垃圾收集器的语言定期扫描内存(以这种或那种方式)来查找未使用的对象,释放与它们相关的资源,最终释放这些对象所使用的内存。

Rust没有GC,它是如何pipe理的?

Rust拥有所有权。 使用仿射types系统 ,它跟踪哪个variables仍然保持在对象上,当这样的variables超出范围时,调用是析构函数。 您可以很容易地看到仿射types系统:

 fn main() { let s: String = "Hello, World!".into(); let t = s; println!("{}", s); } 

产量:

 <anon>:4:24: 4:25 error: use of moved value: `s` [E0382] <anon>:4 println!("{}", s); <anon>:3:13: 3:14 note: `s` moved here because it has type `collections::string::String`, which is moved by default <anon>:3 let t = s; ^ 

这完美地表明,在任何时候,在语言层面上,所有权都被追踪。

这个所有权以recursion的方式工作:如果你有一个Vec<String> (即一个dynamic的string数组),那么每个String都由Vec拥有, Vec本身被variables或另一个对象拥有,等等。variables超出范围,它recursion释放它所持有的所有资源,甚至是间接的。 在Vec<String>的情况下,这意味着:

  1. 释放与每个String关联的内存缓冲区
  2. 释放与Vec本身关联的内存缓冲区

因此,归功于所有权追踪,所有程序对象的生命周期都严格依赖于一个(或几个)函数variables,这些variables最终将超出范围(当它们所属的块结束时)。

注意:使用引用计数( RcArc )可以形成引用的循环,从而导致内存泄漏,在这种情况下,连接到循环的资源可能永远不会被释放。

使用必须手动pipe理内存的语言,堆栈和堆之间的区别变得至关重要。 每次调用一个函数时,在该函数的作用域内包含的所有variables在堆栈上分配了足够的空间。 当函数返回时,与该函数关联的堆栈帧被“popup”堆栈,并释放内存供将来使用。

从实际的angular度来看,这种无意识的内存清理被用作自动内存存储的一种方式,在函数范围的末尾将被清除。

有更多的信息在这里: https : //doc.rust-lang.org/book/the-stack-and-the-heap.html