HowTo: Windows デスクトップヒープ問題の調査と解決方法

対応バージョン :1.0.0
対応エディション :プロフェッショナル版スタンダード版コミュニティー版
対応プラットフォーム :WindowsMac OSX (未対応)Linux (未対応)IBM AIX (未対応)FreeBSD (未対応)HP-UX (未対応)Solaris (未対応)IBM z/OS (未対応)IBM z/Linux (未対応)

Windows 上で、いくつかサービスをインストールしてスタートすると、 追加したサービスが開始できないという問題に遭遇する場合があります。

各サービスでは、Windows システム、フォント、API エレメントなどを保存するのに利用する内部のデスクトップヒープ領域から、 一定量のメモリを割り当てます。 このデスクトップヒープ領域が枯渇すると、user32 システムコールが失敗し始めます。 残念ながら、現在のところ、事前に Windows システムへ問い合わせして、 デスクトップヒープ容量について確認することはできません。 Wrapper プロセスで有効なデスクトップヒープ領域が枯渇すると、 ほとんどの場合、以下のようなエラーに遭遇することになるでしょう。

  • サービス開始の試みで、サービスマネージャーが即座に次のエラーでタイムアウトになります:

    Error 1053: The service did not respond to the start or control request in a timely fashion
    
  • サービスを開始しますが、完全に JVM の起動失敗になり、コード6で終了します。 通常、次のようなエラーを「wrapper.log」ファイルに記録します。

    STATUS | wrapper  | 2011/08/31 16:54:53 | JVM起動中...
    INFO   | jvm 1    | 2011/08/31 16:54:54 | Error loading: C:\Sun\jdk1.6.0_24\jre\bin\server\jvm.dll
    ERROR  | wrapper  | 2011/08/31 16:54:54 | アプリケーションを読み込み中に、JVM が終了しました。
    
  • サービスを開始しますが、コンソールの配置に失敗します。

内部デスクトップヒープに関する説明は、外部サイトをご覧ください。 もし、サービスが非対話サービスとして起動すると、Windows XP 32 ビット版システムで、 デフォルトのヒープ容量は 512 KB ですが、これは 動作しているWindowsバージョン次第で大きく変化します。 Wrapper 自体は各インスタンスごとに 10-15 KB を割り当てます。 しかしながら、起動された JVM もまた最低でも 20 KB を割り当てます。 その正確な値は、動作している Java アプリケーションが何をしているか次第で変化します。 もし Wrapper プロセスをロード(読み込み)している時にヒープ容量が枯渇すると、 上記で示すようなタイムアウト(時間切れ)という結果になります。 もし JVM をロード(読み込み)している時にヒープ容量が枯渇すると、その他の問題になります。

これを書いている現時点で、 Wrapper からデスクトップヒープの残量について Windows へ問い合わせする方法を見つけることができません。 マイクロソフトから提供されているツール「デスクトップヒープモニター」を使い、デスクトップヒープを診断し、 モニタリング(監視)することが可能です。 このツールは、カーネルレベルのドライバーとして動作する必要があるため、Wrapper には不要ですが、アクセスレベルが必要です。

dheapmon.exe の使い方は、マイクロソフトの説明書を参照ください。 基本ステップは次のとおり:

  • 「デスクトップヒープモニター」には、Windows システムシンボルへのアクセス権が必要です。 ほとんどのケースで、一番簡単な方法は、マイクロソフトのシンボルサーバーへアクセスすることです。

    dheapinst.exe -y srv*http://msdl.microsoft.com/download/symbols
    
  • 次に、デスクトップヒープモニターカーネルドライバーをロード(読み込み)する必要があります。

    dheapmon.exe -l
    
  • 最後に、動作させて、全てのデスクトップヒープの現在の状況を収集します。

    dheapmon.exe
    

dheapmon.exe」が動作するとき、以下のように見えるはずです:

dheapmon.exe
Desktop Heap Information Monitor Tool (Version 8.1.2925.0)
Copyright (c) Microsoft Corporation.  All rights reserved.
-------------------------------------------------------------
  Session ID:    0 Total Desktop: (  5824 KB -    7 desktops)

  WinStation\Desktop            Heap Size(KB)    Used Rate(%)
-------------------------------------------------------------
  WinSta0\Default                    3072              8.2
  WinSta0\Disconnect                   64              4.5
  WinSta0\Winlogon                    128              9.8
  Service-0x0-3e7$\Default            512             28.8
  Service-0x0-3e4$\Default            512              2.1
  Service-0x0-3e5$\Default            512              3.1
  SAWinSta\SADesktop                 1024              0.3
-------------------------------------------------------------

上記の例で、「Service-0x0-3e7$\Default」で、 Wrapper は SYSTEM ユーザーとして非対話サービスとして動作しています、 デフォルト SYSTEM ユーザーとして、さらに非対話サービスを追加で開始すると、 次第にこのデスクトップヒープ利用が増量します。

対話サービスとしてサービスを動作させると、WinSta0\Default ヒープ量が増えることになります。

あるユーザーアカウントでサービスを動作させると、それぞれ個別のサービスごとに、 新しく WinStation\Desktop セッションを作成します。

現在のところ、ここに2つの回避策があります:

  • wrapper.ntservice.account]プロパティで、特定のサービスユーザーアカウントとして動作させること。 各サービスには、そのデスクトップと、そのデスクトップヒープを持っています。 これにより、より多くのサービスを動かせるようになりますが、 各サービスは、同じデスクトップで一緒に動作するときよりも、もっと多くのデスクトップヒープを要求します。 一旦、全てのデスクトップヒープの合計が、Session View Space のサイズに達すると、 再度リソース問題に遭遇します。 Windows XP や、その後続バージョンの Windows で、 Session View Space のデフォルト合計サイズは 48 MB です。 レジストリを変更することで、その数字を増加させることができます。

  • マイクロソフトの手順書のとおり、 レジストリを変更することで、非対話デスクトップヒープ容量を増やすことは可能です。 ご存知かと思いますが、レジストリを変更する際には十分に注意してください。

Windows 64 ビット版には、デフォルトで、かなり大きなデスクトップヒープのサイズを用意してありますので、 そのシステム上で問題に遭遇することは、まずありません。