Windows TIPS
[System Environment]
  Windows TIPS TOPへ
Windows TIPS全リストへ
内容別分類一覧へ

原因不明のメモリ不足エラーに対処する方法(デスクトップ・アプリケーション・ヒープ不足エラーに対処する方法)

解説をスキップして設定方法を読む

デジタルアドバンテージ
2000/06/16
2003/01/11 更新
 
対象OS
Windows NT
Windows 2000 Professional
Windows 2000 Server
Windows 2000 Advanced Server
Windows 3.xユーザーを悩ませたシステムの作業用メモリ領域「システム・リソース」の呪縛は、NT以降の32bit化されたWindows OSでは解消されたかのように思えた。
しかし実際には、同等のシステムの作業領域は存在しており、空きメモリがいくらあっても、この領域が不足するとメモリ不足エラーが発生する可能性がある。
特に、パフォーマンス向上を目的として、Windows NT 3.5ではデフォルトの領域サイズが縮小されたため、このエラーが発生しやすい。
これを解消するには、レジストリの設定値を変更する。
 

解説

 16bitの流れを汲むWindows 9xには、システム・リソースと呼ばれるWindowsシステムの作業用メモリ領域があり、新しいウィンドウが生成されたときや、ウィンドウへのグラフィックス描画がなされたときなど、作業データがこの領域に確保されるようになっている。Windows 9xの原点とも呼べるWindows 3.0では、ウィンドウ管理用(USERリソースと呼ばれていた)やグラフィックス描画用(GDIリソースと呼ばれていた)として、それぞれ16bitアドレッシングによる1セグメント(64Kbytes)のメモリ領域が割り当てられていた。残念なことにWindows 3.0では、ウィンドウを幾つか同時に開いたり、巨大なアプリケーションを実行したりすると、特にこのうちのUSERリソースが不足することが多かった。システム・リソースが不足すると、アプリケーションで使用可能なメモリ領域はまだ残っているにもかかわらず、メモリ不足エラーが発生することになる。困ったことに、システム・リソースはWindows自身がそのサイズを固定的に取り決めている管理領域であり、物理的にメモリ・モジュールを増設したりしてもサイズは増えないことだ。

Windows 3.0の使用可能システム・リソース
Windows 3.0ユーザーを悩ませてきたシステム・リソース。たった64Kbytesの領域を使いきると、通常のメモリがいくらあっても「メモリ不足エラー」になってしまった。画面はWindows 3.0のプログラム・マネージャから使用可能システム・リソースを確認したところ。もはや残りは6%しかない。

 これに対しマイクロソフトは、Windows 3.1において、USERリソース用のセグメントを2つ(128Kbytes)に倍加し、リソース不足の問題を回避した。さらにカーネルの32bit対応を行い、4Gbytesのメモリ領域をフラットにアドレッシング可能になったWindows 95では、過去との互換性を維持するうえで必要な要素を下位64Kbytesに残しながら、それ以外のデータは上位のアドレスを使用可能にし、リソース不足問題をほぼ抜本的に解消した(ただし、互換上残された64Kbytesの制限はなくなったわけではない)。

 いうまでもなく、当初から32bitシステムとして設計されたWindows NT(およびその後継のWindows 2000/XP)では、基本的にこのような16bit時代の呪縛は残っていない(以下、特にバージョンに言及する必要がないかぎり、Windows NTコアを持つすべてのWindows OSを総称して「Windows 2000/XP」と表記する)。実際、Windows 2000/XPを使っていても、利用可能メモリは残っているのもかかわらず、メモリ不足エラーが発生するというWindows 3.x当時のようなトラブルはめったに発生しないし、そもそもWindows 3.xユーザーの間ではたびたび話題に登った「システム・リソース」という言葉自体もあまり聞かれなくなった。Windows 2000/XPでは、システム・リソースの制限はなくなったのか?

Windows 2000の「デスクトップ・アプリケーション・ヒープ」とは?

 残念ながら、システムの作業領域が不足することによるメモリ・エラーは、Windows 2000においても発生する可能性がある。これは「デスクトップ・アプリケーション・ヒープ(desktop application heap)」と呼ばれる領域に起因するものである。これはWindows 2000デスクトップで実行される、すべてのウィンドウ・ベースのアプリケーションが使用する領域で、実行されるすべてのプロセスのメモリ空間にマップされ共有される。そして内部には、ウィンドウ管理情報やメニュー・データ、アプリケーションによって作成されたペン、アイコンなどが作業用として保存される。用途としては、ちょうどWindows 3.xのUSERリソースとGDIリソースを1つにしたようなものと考えればよいだろう。このデスクトップ・アプリケーション・ヒープ領域のサイズは、Windows 2000の起動時に決定され、不足したからといってダイナミックに増やされたりしない。つまりWindows 3.xのシステム・リソースと同様の問題が生じる可能性があるわけだ。

 マイクロソフトは、この件に関するサポート技術情報を公開している。

 このドキュメントを読むかぎり、対象となるOSはWindows NTからWindows 2000までで、Windows XPは対象にはなっていない(さらにマイクロソフトのサイトを検索してみたが、関係がありそうな情報は見付からなかった)。単にドキュメントが更新されていないだけなのか、Windows XPでは、Windows 2000から比較してデスクトップ・アプリケーション・ヒープに関する何らかの対応が加えられ、問題が解消しているのかは不明だ。ただし、以下で述べるレジストリ設定については、Windows XPもWindows 2000と同じであった。以下、本稿ではWindows 2000を対象として話を進めるが、Windows XPを使っていて同じような症状に遭遇したときには、同様の方法で対処してみるとよいだろう。

デフォルト・サイズは3Mbytes、制限する理由はパフォーマンスの低下回避

 しかしこのような制限を加える理由は、Windows 9xがその理由とする互換性維持ではない。前述したとおり、このデスクトップ・アプリケーション・ヒープは、すべてのプロセスのメモリ空間にマップされるため、これが不用意に大きくなると、システム・パフォーマンスに重大な影響を及ぼすからだ。ちなみにWindows NTの初期バージョンであるVer.3.1では、デスクトップ・アプリケーション・ヒープのデフォルト・サイズは3Mbytesだったが、次のVer.3.5では、パフォーマンス向上を目的として512Kbytesに縮小された(Windows 2000/XPでは3Mbytesに戻されている)。NT 3.5の大きな特徴の1つはパフォーマンスの向上だった(Windows NTの歴史の詳細については、「特集:Windows 2000とは何か? 『コラム:Windows NTの歴史』」を参照)。つまりデスクトップ・アプリケーション・ヒープのサイズは、それだけシステム性能に及ぼす影響が大きいという証である。

 マイクロソフトの資料によれば、512Kbytesで約2500個のウィンドウを開くことが可能としている。従って3Mbytesなら、単純計算では1万5000個のウィンドウを開けることになる。この数字だけ見れば、デスクトップ・アプリケーション・ヒープが不足するなど到底想像できないだろう。それではなぜ、これが不足するような事態が発生するのか?

最も考えられる原因は、アプリケーションのバグ

 この理由として最も単純に考えられるのは、アプリケーションのバグである。一般に、取得したメモリ領域を、それが不要になっても正しく解放せず、領域の取得を繰り返すことをメモリ・リーク(memory leak。「leak」は「漏れ出た水」の意)と呼ぶ。デスクトップ・アプリケーション・ヒープ不足は、この領域上でメモリ・リークを起こしているアプリケーションが存在している可能性が高い。このようなとき、デスクトップ・アプリケーション・ヒープ領域が必要に応じて拡張される仕様になっていたら、システムのメモリ領域はこのメモリ食いのバグに食べ尽くされてしまうだろう。デスクトップ・アプリケーション・ヒープのサイズが固定されている理由の1つはこれである。


設定方法

レジストリを修正する前に

 デスクトップ・アプリケーション・ヒープが不足すると、新たにアプリケーションを起動しようとしたとき、アクティブ・ウィンドウを切り替えようとしたときなどに、突然「メモリ不足エラー」が通知される。あるいは、このメモリ領域の性格上、「メモリ不足エラー」メッセージ・ボックス自体を正しく表示することすらできないかもしれない。

 デスクトップ・アプリケーション・ヒープのサイズは、レジストリに記録されているので、これを修正して大きな値にすれば、起動時のデスクトップ・アプリケーション・ヒープを増加させることができる。以下にこの方法を述べるが、レジストリを修正する前に、そのエラーが発生した時点で実行されているアプリケーションなどを調べ、メモリ・リークを起こしていそうなものがないかどうかを検討しよう。そして思い当たる節があるなら、そのアプリケーションの使用中止を検討しよう。前述のような理由から、デスクトップ・アプリケーション・ヒープの増加によって、システム・パフォーマンスは低下してしまうからだ。こうした段階を踏んでも、初期値を増加するしかない場合にかぎり、レジストリを修正するようにしよう。

レジストリを修正する

[注意]

レジストリに不正な値を書き込んでしまうと、システムに重大な障害を及ぼし、最悪の場合、システムの再インストールを余儀なくされることもあります。レジストリ・エディタの操作は慎重に行うとともに、あくまで御自分のリスクで操作を行ってください。何らかの障害が発生した場合でも、本Windows Server Insider編集部では責任を負いかねます。ご了承ください。

 レジストリ・エディタを起動し、HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystemsキーを表示して、データ一覧から「Windows」をダブル・クリックするか、「Windows」を選択して[編集]−[変更]メニューを実行する。レジストリ・エディタを起動するには、エクスプローラから%windir%regedit.exeを実行するか、[スタート]ボタンの[ファイルを指定して実行]を選択し、表示されるダイアログで「regedit」と入力して[OK]ボタンをクリックすればよい。レジストリ・エディタは、[スタート]−[プログラム]メニューなどには登録されていない。

レジストリ・エディタを起動する
レジストリ・エディタを起動したら、HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystemsキーを表示し、データ一覧から「Windows」をダブル・クリックする。
  HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\SubSystemsキー。
  この「Windows」をダブル・クリックするか、これを選択した後、[編集]−[変更]メニューを実行する。→

 すると次のような[文字列の編集]ダイアログが表示される。

[文字列の編集]ダイアログ
デスクトップ・アプリケーション・ヒープを変更するには、ここで[値のデータ]にあるパラメータを修正する。
  ここには、Win32サブシステムの起動時のパラメータが保存されている。csrss.exeはクライアント・サーバ・ランタイム・プロセス用のモジュール。
 
「SharedSection」のパラメータ
[値のデータ]でカーソルを移動し、「SharedSection」パラメータを見付ける。
  デスクトップ・アプリケーション・ヒープの初期値を決定するのは、「SharedSection=xxx,yyy」の「yyy」の値。ここにKbytes単位でサイズを指定する。

 ここには、Win32サブシステムの起動時のオプションが記述されている。デスクトップ・アプリケーション・ヒープの初期値は、このオプション中のSharedSection=xxx, yyy」の「yyy」で、ここにKbytes単位でサイズを指定する。例えばWindows NT 3.5なら、デフォルト設定は次のようになっているはずだ。

SharedSection=1024, 512

 Windows 2000およびWindows XPでは、デフォルト設定は次のようになっている。

SharedSection=1024, 3072

 いずれも、第1パラメータ(1024)はグローバル・ハンドル・テーブルなど、すべてのデスクトップで共有されるシステム設定用領域で、これを変更する必要に迫られることはまずない。

 前述のとおり、デスクトップ・アプリケーション・ヒープのWindows NT 3.5でのデフォルト・サイズは512Kbytes、Windows 2000/XPでのデフォルト・サイズは3Mbytes(3072Kbytes)である。ヒープ不足を解消するには、この値を増加させるわけだが、この値がWindowsシステムに与える影響は大きいので、くれぐれも慎重に増加させていただきたい。通常は256Kbytesや512Kbytes単位に増加させれば問題を解消できるはずだ(それでも問題を回避できないときは、前述のとおり別の道を検討すべきである)。

 場合によっては、「SharedSection=」オプションに第3のパラメータが存在することがある。

SharedSection=1024, 3072, 512

 この第3のパラメータ(512)は、ノン・インタラクティブなプロセスに割り当てられるデスクトップ・ヒープのサイズである。こちらも修正に迫られることはまずないので無視してよい。

 以上、設定を変更したら、システムを再起動する。End of Article

更新履歴

【2003/01/11】最新情報を反映して加筆・修正しました。
 
「Windows TIPS」


Windows Server Insider フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Windows Server Insider 記事ランキング

本日 月間