トップ回答者
IISのメモリ使用量について

質問
-
はじめまして。strokmrと申します。
初めて投稿させて頂きます。
IISにまだ慣れていないので、記述が拙いかと思いますが、
宜しく御願い致します。
現在、IISの検証作業を行っています。
環境はWindows Server 2003で、IIS 6.0を使用しています。
仮想ディレクトリを作成し、そこにVB.NETのWebアプリや、
aspxなどを配置して動作させています。
検証作業の目的としては、DBサーバとして導入した前述の環境で
『OutOfMemory』が発生したが、現状の環境のままメモリの使用量を
減らす手段を調べる、というものです。
もちろんアプリケーション的な問題も考えられますが、それらに関しては
別のセクションで行われているので、今回の作業としては範疇外です。
諸先輩方の意見や自分なりの調査で、仮想ディレクトリに配置している
アプリで不要なものを取り除くとメモリの使用量が変わるのではないかと
思い、検証を行いました。
パフォーマンスモニタでロギングして、取り除く前と取り除いた後で
WorkingSet値に違いが出た、という結果は得ることが出来ました。
ただ、この結果を報告しようとした時、論理的な裏づけが全くないことに
気がつきました。このままでは推測からたまたま行き着いた結果に
成りかねません。
IISがWebサイトをロードする際には、配置されているアプリや
その他のファイルを読み込んでいる…といったような事が記載されている
技術的な文書があるか御存じないでしょうか。
宜しく御願い致します。
- 移動 Wang Huang 2012年10月2日 1:41 (移動元:Internet Information Services 5.x, 6.0 - 全般)
回答
-
ASP.NET アプリケーションでの OutOfMemoryException への対処については最近新しいサポート技術情報ができました。御質問の本筋からは外れるかもしれませんが、一応ご参考まで。
ASP.NET Web アプリケーションで System.OutOfMemoryException が発生する場合のトラブルシューティング
ファイル群が読み込まれる時の動作については以下のような概要になるかと思います。ほぼファイルアクセスが主ですので、ProcessMonitor などでモニタするとより詳細が見えるかと思います。
Process Monitor v1.37
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
0) アプリケーションを配置する(aspx、bin\*.dll など)
1) 初回のリクエストを行う
2) bin フォルダの dll が %WinDir%\Microsoft.NET\Framework\<バージョン>\Temporary ASP.NET Files のアプリケーション名フォルダの下層、assembly\dl* フォルダ下層にコピーされる
3) aspx, ascx などの内容を元にソースコードが生成され、それがコンパイルされて dll が作成される (この動きを確認する際には web.config、compilation 要素、debug 属性を true にしておくと、中間ファイルが残るため、より分かりやすくなります)
4) 2)、3) の dll を読み込む
ASP.NET 2.0 の Web サイトプロジェクトや、事前コンパイルの有無などで多少変わりますが、この流れが ASP.NET 最初のバージョン以来の基本的な動きになるかと思います。
ASPX を減らすと、3) の dll が減るので多少 Workingset が減るかと思います。この dll = アセンブリの個数は、パフォーマンスモニタ .NET CLR Loading - Current Assemblies で確認できるかと思います。
上記のサポート技術情報にも記載がありますが、.NET はアセンブリの数が増えるとメモリが断片化しやすい傾向があるので aspx を減らす、bin フォルダに dll を減らす、aspx から自動生成される dll 数を減らすために debug 属性を false にする、といった対処は OutOfMemoryException に対して効果があると思います。
ただし、Workingsets を観測している場合には、断片化の有無や程度は判別しにくいかもしれませんし、効果のほども Workingsets で見ていると数 MB から、多くても数10MB程度かなぁと思います。
以上、参考になれば幸いです。
よろしくお願い致します。
d99
-
こんにちは、naginoです。
> w3wpプロセスのWorkingset値
IISが起動しただけでは、w3wpプロセスは起動しません。
何らかのリクエストがあると、初めて起動します。
d-ninetynine様も記載されているとおり、w3wpプロセス起動の際に仮想フォルダ内にあるaspxファイルのコンパイルなどが
行われていますので、コンパイルに使用するメモリや、コンパイル済みの情報を保持する分、ファイルの有無によって
メモリ使用量に差が出ます。
てっきりw3wpプロセスの起動前の話だと思い込んでいました。
起動後というのであれば、メモリ使用量に差が出るのも納得です。
しかし10MBも差が出るとは、結構大きいものですね。
1事例として勉強になります。
すべての返信
-
こんにちは、naginoです。
# 納期間近のため、フォーラムからご無沙汰しています。
少々状況が把握しづらいのですが、「配置しているアプリで不要なもの」というのは、
誰もアクセスしていないものでしょうか。
その場合、ワーカープロセスが立ち上がらないので、ほとんどメモリ使用量に差は無いはずです。
TechNetで該当の記載がちょっと見つからなかったので、@ITですが、以下のサイトに
「ただしワーカー・プロセスは一定期間リクエストを処理せずにいると、自動的に終了する仕組みになっているので、
初期状態(Webを全くアクセスしていない状態)では1つもw3wp.exeを見つけられないはずだ。
これは、アプリケーション・プールを多数作成しても、アプリケーションがアクセスされない限りは、
無駄にプロセスが起動されることはないということを意味している。」
といった記載があります。
http://www.atmarkit.co.jp/fwin2k/dnsvrguide/iis02/iis1.html
一部のアプリケーションのメモリ使用量が肥大化する傾向がある場合は、ワーカープロセスのリサイクルを、
メモリ使用量をトリガとして設定する方法が一般的かと思います。
http://www.atmarkit.co.jp/fwin2k/dnsvrguide/iis02/iis2.html
メモリ使用量が肥大化しているアプリケーションプールのメモリのリサイクルで、
最大仮想メモリや最大使用メモリを指定することで、ワーカープロセスのリサイクル(プロセスの再起動)を
自動的に行うことができます。
なお、英語のMicrosoftのサイトですと、以下のようなURLがあります。
なお、IIS6.0の日本語での技術情報は意外と少ないですが、以下のURLが全体像を記載しています。
http://www.microsoft.com/japan/technet/windowsserver/2003/technologies/webapp/iis/reskit02.mspx
# 日本語のTechCenterは、操作ガイドぐらいしか見当たりません。
ご参考になれば幸いです。
-
御回答頂き、ありがとうございます。
説明が拙くて申し訳ありません。
いわゆる『不要なもの』というのは、仮想フォルダ内の一部のDLLやaspxで、誰もアクセスはしません。
しかし、同じ仮想フォルダ内に『必要なもの』もあり、それらはアクセスしています。
よって、ワーカ・プロセス(w3wp.exe)は動作しています。
この『アクセスはしないけれども、置いてある』状態と『アクセスしないので、取り除いた』状態を
比較したところ、Workingset値の違いがあったということなのです。
> ワーカープロセスのリサイクル(プロセスの再起動)を自動的に行う
この記事は私も見ていました。
ですが、プロセスの再起動が行われると、それまで行われていた処理が停止、
もしくは中断してしまうのではないかと思い、この設定はスルーしていました。
また、増え続けてしまっている現状で、この設定を行ったとしても、
再起動を繰り返すだけなのでは?と思ってしまったのですが、
その認識は誤りでしょうか。不勉強で恐縮です・・・。
なかなか、情報がないものですね・・・。
試行を重ねて、平均をとってグラフ化して、『ほら、メモリの使用量に変化がありましたよ!』と
するしかないのかと思うようになってきました・・・。
-
こんにちは、naginoです。
「不要なもの」については了解しました。
DLLやaspxは、使用されていなければ関係なさそうな気もしますが、多少はキャッシュや管理情報が
メモリを消費しているのかもしれませんね。
ISAPIならまだしも、仮想フォルダ内のファイルの有無で変化があるというのも、不思議ではありますが。
あと、ワーカープロセスのリサイクルですが、ちょっとネットが不自由な場所に移動したので、記憶を頼りに記述します。
以下誤りにお気づきの識者の方がいらっしゃいましたら、指摘・補足をお願いいたします。
ワーカープロセスの再起動の処理手順は以下の通りです。
1.ワーカープロセスの再起動の条件に合致すると、再起動待ちになる。
2.再起動待ちになったワーカープロセスは、新しい接続を受け入れない。
代わりの新規のワーカープロセスが起動する。
新しい接続は、既存の他のワーカープロセス(Webガーデン)、もしくは新規のワーカープロセスが処理を受け入れる。
3.再起動待ちのワーカープロセスで実行中の処理が無くなると、ワーカープロセスを終了する。
ですので、ASP.NETでInProcのセッション管理をしている場合などはセッション情報が失われますが、
StateServerを利用しているなど適切に設定されている場合は、ユーザーがワーカープロセスの
リサイクルに気が付くことはほとんどありません。
(ASP.NETのキャッシュなどがクリアされるため、新規プロセス起動直後のレスポンスが悪い程度)
Microsoft社のサイト(の一部?)はIISで構築されていることからも解るとおり、
連続運用にも耐えられる仕組みとなっています。
ですので、適切な設計がされていれば、ワーカープロセスのリサイクルを強く避ける必要はありません。
ご参考になれば幸いです。
-
naginoさん、御回答頂き、ありがとうございます。
ワーカプロセスのリサイクルの件、私の食わず嫌い(?)だったようですね。
対策のうちの一つとして別個に試してみようと思います。
ただ、目の前で効果らしきものが出ている「不要なもの」除去による影響についても
裏づけがほしいのです。
こだわってばかりで申し訳ありません。
効果が微量であれば、それほどこだわらなかったのですが、思っていたよりも
その差が大きいため、「これは使える!」と思った次第です。
比較的、手間もかかりませんですし。
海外サイトも探ってはみているのですが、なかなか見つかりません・・・。
-
こんにちは、naginoです。
実際どの程度のメモリの変化があったかは私も気になるところですので、
差し支えなければ教えていただければ幸いです。
せっかくですので、US版TechNetを少し調べてみました。
ASP.NETの場合、「Compiled Execution」を見ると、どうもクライアントからアクセスがあって初めてコンパイルするだけではなく、
動的にファイルの更新をチェックして事前コンパイルしているようです。
そのためaspxやdllのファイルの有無で、その分メモリに差異が出るのかもしれません。
# もしかして「.NET Runtime Optimization サービス(mscorsvw.exe)」でも使っているのでしょうか?
他には見る限りめぼしい情報が見当たりませんでした。
この情報量ですと、裏づけを取るには残念ながら有償サポートに問い合わせるしかなさそうです。
ご参考になれば幸いです。
-
おはようございます、strokmrです。
ずっとお付き合いいただいて恐縮です。
メモリの変化として、ですが、w3wpプロセスのWorkingset値を計測しており、
『不要ファイルが残った状態』だと、初回起動時の平均が40MBほど、
『不要ファイルを削除した状態』だと、初回起動時の平均が30MBほどに
なっていました。
起動してからは、だいたい10MBの差を保ちながら動作をしていました。
naginoさんに調べていただいた文書に近いものになりますが、
昨日、さらに調べてみると以下のような文書がありました。
『IIS 5.0 および 6.0 における ASP.NET アプリケーションのライフ サイクルの概要』
http://msdn.microsoft.com/ja-jp/library/ms178473.aspx
これによると、最初の要求があった時、
『アプリケーションのグローバル リソースがコンパイルされ、
リソース アセンブリがビルドされます。アプリケーションの
Binフォルダ内のアセンブリは、リソース アセンブリにリンクされます。』
と、ありました。
これを
Binフォルダにあるファイルは起動時にコンパイルされるので、
そのファイルの数を減らせば、コンパイルされる数も減り、
使用するメモリの量も減る、
と都合よく解釈できないかなと文書の内容を確認しているところです。
有償サポートは使わずに・・・と思って、MSDNオンラインコンシェルジェで、
資料の検索を御願いしてみましたが、結局見つからなかったとの回答が来ていました。
有償サポートを使うには、社内的な云々があって時間がかかってしまうので、
暗黙的にタブーとされているのです。
といっても、あまり皆さんのお手を煩わせるわけにも行かないので、どこかで線引きを
しないといけませんね・・・。
-
ASP.NET アプリケーションでの OutOfMemoryException への対処については最近新しいサポート技術情報ができました。御質問の本筋からは外れるかもしれませんが、一応ご参考まで。
ASP.NET Web アプリケーションで System.OutOfMemoryException が発生する場合のトラブルシューティング
ファイル群が読み込まれる時の動作については以下のような概要になるかと思います。ほぼファイルアクセスが主ですので、ProcessMonitor などでモニタするとより詳細が見えるかと思います。
Process Monitor v1.37
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
0) アプリケーションを配置する(aspx、bin\*.dll など)
1) 初回のリクエストを行う
2) bin フォルダの dll が %WinDir%\Microsoft.NET\Framework\<バージョン>\Temporary ASP.NET Files のアプリケーション名フォルダの下層、assembly\dl* フォルダ下層にコピーされる
3) aspx, ascx などの内容を元にソースコードが生成され、それがコンパイルされて dll が作成される (この動きを確認する際には web.config、compilation 要素、debug 属性を true にしておくと、中間ファイルが残るため、より分かりやすくなります)
4) 2)、3) の dll を読み込む
ASP.NET 2.0 の Web サイトプロジェクトや、事前コンパイルの有無などで多少変わりますが、この流れが ASP.NET 最初のバージョン以来の基本的な動きになるかと思います。
ASPX を減らすと、3) の dll が減るので多少 Workingset が減るかと思います。この dll = アセンブリの個数は、パフォーマンスモニタ .NET CLR Loading - Current Assemblies で確認できるかと思います。
上記のサポート技術情報にも記載がありますが、.NET はアセンブリの数が増えるとメモリが断片化しやすい傾向があるので aspx を減らす、bin フォルダに dll を減らす、aspx から自動生成される dll 数を減らすために debug 属性を false にする、といった対処は OutOfMemoryException に対して効果があると思います。
ただし、Workingsets を観測している場合には、断片化の有無や程度は判別しにくいかもしれませんし、効果のほども Workingsets で見ていると数 MB から、多くても数10MB程度かなぁと思います。
以上、参考になれば幸いです。
よろしくお願い致します。
d99
-
こんにちは、naginoです。
> w3wpプロセスのWorkingset値
IISが起動しただけでは、w3wpプロセスは起動しません。
何らかのリクエストがあると、初めて起動します。
d-ninetynine様も記載されているとおり、w3wpプロセス起動の際に仮想フォルダ内にあるaspxファイルのコンパイルなどが
行われていますので、コンパイルに使用するメモリや、コンパイル済みの情報を保持する分、ファイルの有無によって
メモリ使用量に差が出ます。
てっきりw3wpプロセスの起動前の話だと思い込んでいました。
起動後というのであれば、メモリ使用量に差が出るのも納得です。
しかし10MBも差が出るとは、結構大きいものですね。
1事例として勉強になります。