我理解Rust没有垃圾收集器,并且想知道当绑定超出范围时如何释放内存.
所以在这个例子中,我理解Rust在超出范围时回收分配给'a'的内存.
{
let a = 4
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题,首先是如何发生这种情况,其次这不是一种垃圾收集?它与"典型"垃圾收集有何不同?
Mat*_* M. 38
无论策略如何,管理程序中资源(包括内存)的基本思想是可以回收与无法访问的"对象"相关的资源.超越内存,这些资源可以是互斥锁,文件句柄,套接字,数据库连接......
带有垃圾收集器的语言会定期扫描内存(以这种或那种方式)查找未使用的对象,释放与之关联的资源,最后释放这些对象使用的内存.
Rust没有GC,它如何管理?
Rust拥有所有权.使用仿射类型系统,它跟踪哪个变量仍然保持在一个对象上,当这样的变量超出范围时,调用它的析构函数.您可以非常轻松地看到仿射类型系统:
fn main() {
let s: String = "Hello, World!".into();
let t = s;
println!("{}", s);
}
Run Code Online (Sandbox Code Playgroud)
产量:
<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;
^
Run Code Online (Sandbox Code Playgroud)
这完美地说明了在任何时间点,在语言层面,都会跟踪所有权.
这个作品的所有权递归:如果你有一个Vec<String>(即动态字符串数组),那么每个String由拥有Vec其本身是由一个变量或其他物体,拥有等等......因此,当变量超出范围,它递归地释放了它所拥有的所有资源,甚至间接地释放了它.在这种情况下,Vec<String>这意味着:
StringVec自身关联的内存缓冲区因此,由于所有权跟踪,所有程序对象的生命周期严格依赖于一个(或几个)函数变量,这些函数变量最终将超出范围(当它们所属的块结束时).
注意:这有点乐观,使用引用计数(Rc或Arc)可能形成引用循环,从而导致内存泄漏,在这种情况下,与循环相关的资源可能永远不会被释放.
使用必须手动管理内存的语言,堆栈和堆之间的区别变得至关重要.每次调用函数时,都会在堆栈上为该函数范围内包含的所有变量分配足够的空间.当函数返回时,与该函数关联的堆栈帧从堆栈"弹出",并释放内存以供将来使用.
从实际角度来看,这种无意的内存清理被用作自动存储器存储的一种方法,它将在功能范围结束时被清除.
这里有更多信息:https: //doc.rust-lang.org/book/the-stack-and-the-heap.html