铁锈有什么,而不是垃圾收集器?
一个基本的问题,但我是新的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>
的情况下,这意味着:
- 释放与每个
String
关联的内存缓冲区 - 释放与
Vec
本身关联的内存缓冲区
因此,归功于所有权追踪,所有程序对象的生命周期都严格依赖于一个(或几个)函数variables,这些variables最终将超出范围(当它们所属的块结束时)。
注意:使用引用计数( Rc
或Arc
)可以形成引用的循环,从而导致内存泄漏,在这种情况下,连接到循环的资源可能永远不会被释放。
使用必须手动pipe理内存的语言,堆栈和堆之间的区别变得至关重要。 每次调用一个函数时,在该函数的作用域内包含的所有variables在堆栈上分配了足够的空间。 当函数返回时,与该函数关联的堆栈帧被“popup”堆栈,并释放内存供将来使用。
从实际的angular度来看,这种无意识的内存清理被用作自动内存存储的一种方式,在函数范围的末尾将被清除。
有更多的信息在这里: https : //doc.rust-lang.org/book/the-stack-and-the-heap.html