The future starts today

Webとか英語とか育児とかに関する雑記

【Rust】メモリ管理(スタックとヒープ)

Memory

ずっとJavaScriptを書いてきた身からすると、メモリ管理という単語はあまり触れたくない単語。
ブラウザのガベージコレクターが良い感じにやってくれるというくらいの認識しかなかった。

そこでRustに入門して、メモリ管理の第一歩を踏み出してみる。

Rustにはスタックとヒープという2種類のメモリ管理方法がある。

スタックとは

下から順に上に重ねていく方式。(last in, first out)
スコープが外れたタイミングで解放されていく。

fn next() {
    let y = 20;
    let z = 30;
}

fn main() {
    let x = 10;

    next();
}

上記の例では、main関数でxのメモリが確保され、foo関数でy, zのメモリが確保される。
foo関数から抜けたタイミングでy, zはスコープ外となり、メモリが解放される。
そして、main関数が終わると全ての値が解放される。

スタックは単純な仕組みな故、高速である。

ヒープとは

順序関係なしにメモリ確保、解除ができる。
Box<T>型を用いた場合はヒープ領域にメモリが確保されるようになっている。

スタックの時とは異なり、メモリ確保は一番後ろの番地から行われる。

ところで<T>って何?

Rustのexampleを見ていると至る所に<T>が出てくる。
これはジェネリック型というやつで、簡単に言えばどんな型でも柔軟に対応しますよという型。(間違ってたらすまん)

通常、TypeのTを取って<T>と表記される場合がほとんどだが、別に何のアルファベットでも良いらしい。

話を戻しまして、

fn main() {
    let x = Box::new(5);
    let y = 10;
}

上記の例の場合、Box::new(5)によって生成された値はヒープ領域に保存され、xはその番地へのポインタをスタック上で保持する。
main関数が終わり、xがスタック上から解放されるタイミングでヒープ領域の値も解放される。

ヒープは自由度が高い故にコストが高く、スタックに比べると速度が遅い。

まとめ

基本的にはスタック形式でメモリ管理が行われるので、関数スコープを抜けたタイミングでメモリは解放されていく。
スコープを出てもメモリを保持したい場合にヒープを使うのだろうか。
まだ分からないことがたくさんあるので勉強せな。