10.1 スタックとヒープ

単純化すると、メモリは次のように分類できます。

スタック

関数呼び出し
ローカル変数
比較的小さく寿命が明確な値

高速で自動的に解放されます。

ヒープ

実行時に大きさが決まるデータ
寿命が関数呼び出しを超えるデータ
オブジェクトや動的配列

解放方法は言語によって異なります。


10.2 ガベージコレクション

不要になったオブジェクトを実行環境が検出し、解放します。

代表例:

Java
C#
Go
JavaScript
Python
PHP
Ruby

開発者が明示的にメモリを解放する必要は基本的にありません。

ただし、次のコストがあります。

実行時オーバーヘッド
停止時間の可能性
メモリ解放タイミングが完全には予測できない

10.3 所有権

Rustでは、ガベージコレクタの代わりに所有権でメモリを管理します。

基本原則は次です。

値には所有者がいる
所有者がスコープを抜けると値が解放される
同時に安全な参照規則を守る
{
    let name = String::from("Taro");
}
// ここで自動解放

所有権が移動する場合があります。

let a = String::from("hello");
let b = a;

// aは以後使用不可

これは二重解放や解放後参照をコンパイル時に防ぐ仕組みです。


10.4 借用

所有権を移さず、一時的に値を参照します。

fn length(value: &String) -> usize {
    value.len()
}

可変参照にはより厳しい規則があります。

fn append(value: &mut String) {
    value.push_str("!");
}

Rustの所有権・借用は特殊に見えますが、解決している問題は他言語と共通です。

誰が値を管理するのか
誰が変更できるのか
いつ解放できるのか
同時アクセスは安全か