Skip to content

MS_ThreadStack

nishi_74322014 edited this page Aug 3, 2026 · 1 revision

スレッドのスタック

概要

  • スタック・オーバーフローはなぜ起きるのか?と言えば、
    OSが確保したスレッドのスタックが、再帰呼出し等によって、領域超過を起こすため。

  • スレッドのスタックには、

    • 各関数のスタック・フレームが
      • 引数、戻り値、ローカル変数
      • 戻り先の呼出し元へのポインタ
    • 各関数の呼出し履歴分

    積まれることになる。

詳細

基礎

基本的に 1 スレッド 1MB のメモリ(アドレス空間)を消費する。

スレッドのスタックのメモリ予約・確保については、

  • OS がスレッド作成時にスタックを予約する(基本 1MB)。
  • OS が関数呼び出しの際にスタックを積む(コミット)。

という動作になる。ユーザによる制御は不要。

スタックの最上位のページは既にコミットされており、
スタックに最上位まで積まれ二重にコミットしようとした場合に
スタックオーバーフローという例外が発生する。

移行メモ: ここで言う「最上位のページ」は、 スタック末端に置かれる ガード ページのこと。 スタックが伸びてガード ページに触れると、OS が次のページをコミットして ガード ページをひとつ下へずらす。 予約領域の末端まで達し、もうずらせなくなった時点で スタック オーバーフロー(STATUS_STACK_OVERFLOW)になる。

スタックの成長はメモリの成長とは(アドレス空間から)逆方向になる。

  • メモリの成長 : 0 → 4GB(16TB) の方向
  • スタックの成長 : 4GB(16TB) → 0 の方向

※ 関数の呼び出し規則によって積まれ方の詳細は若干違う。

スタック・サイズの変更

  • /STACK のリンカ・オプションで予約サイズなどを変更可能。
  • EDITBIN ツールを使用して変更可能(ビルド済みの EXE に対して)。
  • .NET では Thread のコンストラクタで maxStackSize を指定できる
    (ただしメイン スレッドには適用されない)。

IIS上でのスタック・サイズ

IIS 上ではスタック・サイズが小さいらしい。

※ このため、開発時(コンソール/WinForms)では通らないのに
IIS 上でのみスタック オーバーフローする
、という現象が起こりうる。
深い再帰はループへ書き換えるのが確実な対処。

補足: .NET では StackOverflowException はキャッチできない (.NET 2.0 以降、プロセスが即座に終了する)。 try/catch で握り潰す設計はできないため、 再帰の深さを設計時に抑えるしかない。

参考


Tags: Windows, メモリ管理, 障害対応, 性能, デバッグ

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally