メモリ
データやプログラムの一時的な保存場所。
メモリには「アドレス」と「メモリ領域(記憶領域)」がある
アドレス
コンピュータ内のメモリにデータを保存する時に、そのデータを格納するメモリに元から付けられている番号(住所)のこと
16進数で表現される
メモリ領域
データやプログラムが保存される領域。
メモリ領域には「データ」と「命令」が入っている。
格納場所は、紐づいているアドレスによって特定される
Golangのメモリアドレスとは
変数の前に「&」をつけることで、アドレスを取得することができる。
「&」を付けなければ、メモリ領域のデータを取得してくる。
Golangのポインター変数とは
「アドレスが格納された変数」の前に「*」をつけることでポインター変数を定義できる。
ポインターとは
メモリアドレスを格納し、そのアドレスのメモリ領域の値にアクセスできる変数。
Golangのポインター型とは
型名の前に「*」を付けたデータ型のこと
ポインタ型にはアドレスを代入する
ポインター型で定義された変数はポインター変数となり、挙動は上記と同じことをする
値渡し
メモリ領域の値をそのままコピーして、別のメモリ領域に格納すること。
別のメモリ領域に格納しているため、コピーしたもののアドレスは変化する
参照渡し
アドレスを別のメモリ領域に格納すること。
このアドレスを元に、参照元のメモリ領域の値にアクセスすることができる。
メモリ領域の種類
メモリのアドレスには「低位アドレス」と「高位アドレス」がある
低い方から順番に「プログラム領域」→「静的領域」→「ヒープ領域」→「スタック領域」が割り当てられる
メモリに各種のメモリ領域が割り当てられる参考図
メモリ全体があったとして、低位アドレスから順番に上記の領域が割り当てられるようなイメージ
プログラム領域
機械語に変換されたプログラムの命令が格納される。
実行時に1行ずつ実行する。
静的領域
グローバル変数、定数などが配置される。
プログラム開始時に初期化され、プログラムの寿命中存在し続ける
ヒープ領域
動的データが保持される
関数スコープに縛られずにオブジェクトを確保しておける。
・確保、解放が遅い
・寿命は自由
・サイズが大きい
・サイズが動的に決定される
・newなどで確保される
・Goコンパイラでメモリを確保できない値がヒープにエスケープされる
・GCされる
・Goコンパイラとランタイムによって、いつ使用され、いつクリーンアップされるか把握できない
スタック領域
静的なデータが保持される
・GCを使わないため効率的
・確保、解放が早い
・寿命が短い
・サイズが小さい
・ローカル変数、引数、返り値、静的構造体、プリミティブ値など
・レキシカルスコープに紐づいたメモリが割り当てられる
・Goコンパイラが、メモリを確保する
・goroutineスタックが格納される
各領域まとめ
Golangのヒープとスタック
内部的には優先的にスタックを使用するようになっている。
参考資料