katapedia

プログラム

メモリ

スタックとヒープ

ヒープのほうがスタックよりも遅い。遅い理由は領域の確保と解放が要因。

rust-jpのslackから転載

スタックは関数の呼び出しで確保(領域を拡張)して、関数の戻りで開放する(領域を巻き戻す)ので管理が非常に簡単です。たとえば巻き戻すときは(CPUのアーキテクチャに依存しますが)一般的にマシン語の命令一つで済みます。また(OSに依存しますが)スタック領域はスレッドごとに独立したものが用意されるのが一般的なので、確保・開放に関する排他制御も不要です。 ヒープは任意の時点で確保・開放できますし、複数のスレッドで共有できますので、管理が複雑になります。そのためヒープアロケータという種類のライブラリを通して管理します。 たとえば、プログラムの実行が始まってから時間が経つとヒープ用のメモリ領域の中には使用中のスペースと開放済みのスペースが混在した状態になってきます。プログラムがヒープに新たにスペースを確保したいとき、ヒープアロケータはこの開放済みのスペースを探索して、ちょうどいい大きさのスペースを見つけなければなりません。この管理が下手だとメモリの断片化(フラグメンテーション)が酷くなり、性能が劣化したり無駄にメモリを使ったりします。また、確保や開放の要求は複数のスレッドから同時に来るかもしれませんので、ヒープアロケータ内で排他制御も必要になります。 ヒープアロケータをナイーブに実装するとパフォーマンスがかなり悪くなります。そのため様々な設計や高速化のテクニックがあり、用途に応じたいろいろなヒープアロケータの実装があります。たとえばマルチスレッドなサーバープロセスに適したものがあったり、組み込みシステムやWebAssemblyに適したものがあったりという感じです。 どのような環境でどのヒープアロケータを使うのかによって性能が変わってきますが、いずれの場合でも、スタックよりもヒープの方が管理が複雑になり、確保と解放により長い時間がかかると考えてかまいません。 と、長々と書きましたが、ヒープであってもその管理にかかる時間はファイルシステムやネットワークのアクセスにかかる時間とは比べ物にならないくらい短いものです。ですからほとんどのプログラムでは、データをスタックとヒープのどちらに置いているかは気にする必要はなさそうです。もし違いが問題になるようなプログラムを書くときはこのことを思い出してください