Skip to content

MS_DesktopHeap

nishi_74322014 edited this page Aug 3, 2026 · 1 revision

デスクトップ・ヒープ

概要

デスクトップ・ヒープは、ウィンドウステーション内の
デスクトップオブジェクト(GDIオブジェクトを除く)を格納する。

構成

デスクトップ・ヒープの構成は以下の通り。

デスクトップ・ヒープのストレージ領域

カーネル・アドレス空間 - セッション・スペース ┬→ セッション・イメージ・スペース(Session Image Space)
                                              ├→ セッション構造(Session Structure)
                                              ├→ セッション・ビュー・スペース(Session View Space) → デスクトップ・ヒープ
                                              └→ セッション・ページ・プール(Session Page Pool)

デスクトップ・ツリーとデスクトップ・ヒープの構成

┬ Session 0
│ ├--- WinSta0(対話型ウィンドウステーション)
│ │    ├--- Default(対話型デスクトップ)
│ │    ├--- Disconnect(対話型デスクトップ)
│ │    └--- Winlogon(対話型デスクトップ)
│ ├--- Service-0x0-3e7$(非対話型ウィンドウステーション)
│ │    └--- Default(非対話型デスクトップ)
│ ├--- Service-0x0-3e4$(非対話型ウィンドウステーション)
│ │    └--- Default(非対話型デスクトップ)
│ └--- SAWinSta(非対話型ウィンドウステーション)
│      └--- SADesktop(非対話型デスクトップ)
│
└ Session 1
  └--- WinSta0(対話型ウィンドウステーション)
       ├--- Default(対話型デスクトップ)
       ├--- Disconnect(対話型デスクトップ)
       └--- Winlogon(対話型デスクトップ)
  • Vista以降では、サービスのセッションは常に Session 0 になる。
  • Session 0 はサービスのみを実行するようになったため、
    初回ログインしたユーザのセッションは Session 1 となる。以降 Session 2、3、4…

※ 上図の Service-0x0-3e7$ / Service-0x0-3e4$ は、
末尾の 16 進数がログオン セッション ID に対応しており、
3e7 = LocalSystem、3e4 = NetworkService の非対話型ウィンドウステーション
ビルトイン システム アカウントを参照)。

デスクトップ・ヒープの構成

デスクトップ毎のデスクトップ・ヒープ領域は、
システムのデフォルト値および設定されているレジストリの値を元に、

  • 「標準ヒープ」
  • 「対話型ヒープ」
  • 「非対話型ヒープ」

の3つの領域により構成される。

デスクトップ・ヒープ領域のイメージ

標準ヒープ 対話型ヒープ - WinSta0 非対話型 ・・・ 非対話型ヒープ
各デスクトップ・ヒープ領域の値 各デスクトップ・ヒープ領域の値 各デスクトップ・ヒープ領域の値 ・・・ 各デスクトップ・ヒープ領域の値
全デスクトップ・ヒープの容量

デスクトップ毎にダイナミックに確保される「非対話型ヒープ」の数が、
「全デスクトップ・ヒープの容量」と「各デスクトップ・ヒープ領域の値」で自動的に決定される。

この制約はVista以降で改良されており、「非対話型ヒープ」(全容量)は
デスクトップ・ヒープが Dynamic Kernel Space に実装され、ダイナミックに拡張される。
これにより、「全デスクトップ・ヒープの容量」は、チューニング不要となった。

ただし、「各種デスクトップ・ヒープ」のサイズの問題は発生する。

サーバでは、「標準ヒープ」と「対話型ヒープ」の容量は変更しないため、
「全デスクトップ・ヒープの容量」と「非対話型ヒープの容量」により決定される。

※ 設定値は
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystems\Windows
SharedSection=<標準>,<対話型>,<非対話型>(単位 KB)で確認できる。

各ヒープの説明

各ヒープの容量

OSによって異なる。

標準ヒープ

  • デスクトップに共有される。
  • USERオブジェクトを保持する。
  • グローバル・ハンドルテーブルや、共有システムの設定が含まれる。
  • 通常、この領域サイズの変更の必要はない。

対話型ヒープ

セッションに唯一の対話型のウィンドウステーション
デスクトップが使用する。
(WinSta0 には、Winlogon、Default、Screen-saver の3つのデスクトップがある)

こちらには、USERオブジェクトが格納される。

通常、クライアントOSにてウィンドウの立ち上げすぎなどに起因して
対話型が枯渇することがある(通常、サーバOSでは問題にならない)。

非対話型ヒープ

非対話型のウィンドウステーションデスクトップが使用する。

※ 実務でよく問題になるのは、多数の Windows サービスや
Office のサーバーサイド オートメーションを動かした結果、
非対話型ヒープが枯渇してプロセス起動に失敗する
ケース。
症状は「CreateProcess が失敗する」「サービスが起動しない」など、
一見メモリ不足に見えないのが厄介。

その他の用語説明

USERオブジェクトとGDIオブジェクト

Windows ウィンドウ マネージャーによって管理される、

  • ウィンドウ要素(ウィンドウやメニューなど)と
  • グラフィック要素(ペン、ブラシ、描画領域など)を

表す 2 つのリソース(USER オブジェクトと GDI オブジェクト)

USERオブジェクト

  • ウィンドウ
  • ウィンドウ位置
  • メニュー、アイコン
  • カーソル(マウスの絵)
  • キャレット(TextBox の I)
  • フック、DDE、アクセラレータ テーブル(メニューのキーボード ショートカット)

などのユーザー インターフェイス要素を表す。

USERオブジェクトの使用するメモリはデスクトップ・ヒープから割り当てられる。

GDIオブジェクト

  • フォント
  • ビットマップ
  • ブラシ
  • ペン
  • デバイス コンテキスト(描画領域)

などのグラフィックス デバイス インターフェイス要素を表す。

GDIオブジェクトの使用するメモリは

  • ページ プール
  • セッション プール

から割り当てられる。

USERオブジェクトとGDIオブジェクトの最大値

  • 1つのセッション当たり、其々 65,536 のハンドルだが、
    1つのセッション当たり開くことができるユーザ・ハンドルの最大数は通常より低い(10,000程度)。
  • さらにユーザ・ハンドルのプロセスごとのデフォルト限界がある。
    どのプロセスも、其々 10,000 個以上の USER オブジェクトと GDI オブジェクトを作成することはできない。

※ プロセスごとの上限(既定 10,000)はレジストリ
GDIProcessHandleQuota / USERProcessHandleQuota)で変更できるが、
上限に達するのはハンドル リークが原因であることが多く、
まずはリークを疑うべき。タスク マネージャーの「USER オブジェクト」
「GDI オブジェクト」列で監視できる。

参考


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

NetDevInfraWiki

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

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally