Rustにはガベージコレクタがないことを理解しており、バインディングがスコープ外になったときにメモリがどのように解放されるのか疑問に思っています。
したがって、この例では、Rustがスコープ外になったときに 'a'に割り当てられたメモリを再利用することを理解しています。
{
let a = 4
}
私がこれに関して抱えている問題は、第一にこれがどのように起こるのか、そして第二にこれは一種のガーベッジコレクションではないのですか? 「典型的な」ガベージコレクションとはどう違うのですか?
プログラム内のリソース(メモリを含む)を管理する基本的な考え方は、どのような戦略であっても、到達できない「オブジェクト」に関連付けられたリソースを回収できるということです。メモリを超えて、これらのリソースは相互排他ロック、ファイルハンドル、ソケット、データベース接続などです。
ガベージコレクターを備えた言語は、メモリを(何らかの方法で)定期的にスキャンして未使用のオブジェクトを見つけ、それらに関連付けられたリソースを解放し、最終的にそれらのオブジェクトによって使用されたメモリを解放します。
RustにはGCがありませんが、どのように管理しますか?
Rustには所有権があります。 アフィン型システム を使用して、どの変数がまだオブジェクトを保持しているかを追跡し、そのような変数がスコープ外になると、デストラクタを呼び出します。アフィン型システムは、実際にはかなり簡単に見ることができます。
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;
^
これは、言語レベルでいつでも所有権が追跡されることを完全に示しています。
この所有権は再帰的に機能します:Vec<String>
(つまり、文字列の動的配列)がある場合、各String
は、変数または別のオブジェクトが所有するVec
によって所有されます。など、このように、変数が範囲外になると、間接的にであっても、保持していたすべてのリソースを再帰的に解放します。 Vec<String>
の場合、これは次のことを意味します。
String
に関連付けられたメモリバッファの解放Vec
自体に関連付けられているメモリバッファを解放するしたがって、所有権の追跡のおかげで、すべてのプログラムオブジェクトのライフタイムは1つ(または複数)の関数変数に厳密に結び付けられ、最終的に(それらが属するブロックが終了するとき)スコープから外れます。
注:これは少し楽観的で、参照カウント(Rc
またはArc
)を使用して、参照のサイクルを形成し、メモリリークを引き起こす可能性があります。サイクルに関連付けられたリソースが解放されることはありません。
メモリを手動で管理する必要がある言語では、スタックとヒープの区別が重要になります。関数を呼び出すたびに、その関数のスコープ内に含まれるすべての変数に十分なスペースがスタックに割り当てられます。関数が戻ると、その関数に関連付けられたスタックフレームがスタックから「ポップ」され、メモリは将来の使用のために解放されます。
実用的な観点から、この不注意なメモリクリーニングは、関数のスコープの終わりにクリアされる自動メモリストレージの手段として使用されます。
詳細については、こちらをご覧ください: https://doc.Rust-lang.org/book/the-stack-and-the-heap.html