-
Notifications
You must be signed in to change notification settings - Fork 0
MS_DesktopHeap
-
TOP > インフラストラクチャ > メモリ管理
- デスクトップ・ヒープ
- ウィンドウステーション
- デスクトップ
デスクトップ・ヒープは、ウィンドウステーション内の
デスクトップオブジェクト(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 が失敗する」「サービスが起動しない」など、
一見メモリ不足に見えないのが厄介。
Windows ウィンドウ マネージャーによって管理される、
- ウィンドウ要素(ウィンドウやメニューなど)と
- グラフィック要素(ペン、ブラシ、描画領域など)を
表す 2 つのリソース(USER オブジェクトと GDI オブジェクト)
- ウィンドウ
- ウィンドウ位置
- メニュー、アイコン
- カーソル(マウスの絵)
- キャレット(TextBox の I)
- フック、DDE、アクセラレータ テーブル(メニューのキーボード ショートカット)
などのユーザー インターフェイス要素を表す。
USERオブジェクトの使用するメモリはデスクトップ・ヒープから割り当てられる。
- フォント
- ビットマップ
- ブラシ
- ペン
- デバイス コンテキスト(描画領域)
などのグラフィックス デバイス インターフェイス要素を表す。
GDIオブジェクトの使用するメモリは
- ページ プール
- セッション プール
から割り当てられる。
- 1つのセッション当たり、其々 65,536 のハンドルだが、
1つのセッション当たり開くことができるユーザ・ハンドルの最大数は通常より低い(10,000程度)。 - さらにユーザ・ハンドルのプロセスごとのデフォルト限界がある。
どのプロセスも、其々 10,000 個以上の USER オブジェクトと GDI オブジェクトを作成することはできない。
※ プロセスごとの上限(既定 10,000)はレジストリ
(GDIProcessHandleQuota / USERProcessHandleQuota)で変更できるが、
上限に達するのはハンドル リークが原因であることが多く、
まずはリークを疑うべき。タスク マネージャーの「USER オブジェクト」
「GDI オブジェクト」列で監視できる。
Tags: Windows, メモリ管理, 障害対応, 性能, デバッグ
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。