- PR -

WebServiceのbinフォルダ内の更新時の動作について

1
投稿者投稿内容
あさべー
会議室デビュー日: 2005/06/03
投稿数: 11
投稿日時: 2005-06-20 00:38
いつも参考にさせて頂いております。

C#にてWebサービスを開発しておりますが
本Webサービスでは、
参照するDLLをあらかじめ参照設定しておけない理由があり、
System.Reflection.Assemblyクラスにて読み込んで使用しています。
そのため、これらのDLLを更新する場合はWebサービスのbinフォルダに直接上書きしております。

現在、これらのDLLのどれかひとつでも更新されると、その後の初回起動時に何十秒もの時間がかかってしまっています。

この原因として
・binフォルダ内のファイルが更新された場合、Webサービスのドメインが再起動されること
・binフォルダ内のDLLの総数が1000個近くになっていること

を考えていますが、詳細な原因まで判断しかねています。

これらの現象に関して特に次の2点について
教えていただけませんでしょうか。

・ドメインの再起動時にどのような処理が行われているのか
(全DLLに対してなんらかのチェック処理をしているのか、もしかして全DLLをあらかじめメモリに乗っけているのか?など)
・binフォルダ更新時にアプリケーションを再起動しないですむ設定

宜しくお願いします。
nodera
大ベテラン
会議室デビュー日: 2003/09/08
投稿数: 200
投稿日時: 2005-06-20 11:17
こんにちは。

>・ドメインの再起動時にどのような処理が行われているのか
ワーカープロセスが再起動されます。プロセスの開始に伴うオーバーヘッドや、Application_OnStartイベントが動作するので、そこで時間のかかる処理が行われていれば、何十秒もかかってしまうことはありえるかもしれません。
1000個のDLLが問題であるかどうかは、同一環境で、DLLが数個のWebアプリケーションと、パフォーマンスを比べてみれば分かるかと思います。(Application_OnStart等の初期起動で発生するイベント内容は同一条件にする必要があります。そこで1000個のDLLをロードしてたりしませんよね?)多分、それほどの違いは発生しないでしょう。

>・binフォルダ更新時にアプリケーションを再起動しないですむ設定
多分無いです。.NET Frameworkは同一ドメインに読み込んだDLLをアンロードすることや入れ替えることは出来ません。なので、DLLが入れ替わったときにワーカープロセスの再起動がかかります。
あさべー
会議室デビュー日: 2005/06/03
投稿数: 11
投稿日時: 2005-06-20 11:42
noderaさん、返信ありがとうございます。

引用:
同一環境で、DLLが数個のWebアプリケーションと、パフォーマンスを比べてみれば分かるかと思います。(Application_OnStart等の初期起動で発生するイベント内容は同一条件にする必要があります。そこで1000個のDLLをロードしてたりしませんよね?)多分、それほどの違いは発生しないでしょう。


 まず、Application_StartでDLLのロードは行っておらず、他に特に重い処理もしていません。

 次に、パフォーマンステストの件ですが
実はおっしゃるように
同一環境でDLLの数を大きく変えてパフォーマンステストも行ってみたのです。
その結果、DLLの数によって起動時間は大きく変わりました。
 また、DLLのサイズの合計が変わらないという条件下(ファイルの数⇔1ファイルのサイズ)で
ファイルの数を変えていってパフォーマンステストを行いました。
その結果として
ファイルサイズが大きくてもファイル数が多くても起動時間は大きくなる
(ただしどちらかといえばファイル数が多い方がより起動時間が大きくなる)
という微妙な結果が出てしまい、起動時にファイルを走査しているだけなのか、メモリに載せたりしているのか等の
判断がつかなかった次第です。

もう少し検証してみます。
ありがとうございました。
D, an alchemist
会議室デビュー日: 2005/02/02
投稿数: 11
投稿日時: 2005-06-20 12:01
こんにちわ。

bin フォルダの中身や as?? ファイルを書き換えると、ASP.NET はアプリケーションを再起動をすると思います(パフォーマンスカウンタ ASP.NET の Application Restarts がカウントアップすると思います)。

ASP.NET ワーカープロセス内部には、各アプリケーションごとにアプリケーションドメインが作られているようですので、更新を感知するとまずアプリケーションドメインごとアセンブリをごそっとアンロードし、次にアプリケーションドメインを再生成してからアセンブリを全て再読み込みしなおすみたいです。

ですので、bin フォルダ内のモジュールを更新すると、1000個アンロードして、再度ロードするという作業が発生すると思います。ここをスピードアップさせるのは難しいと思います。可能性レベルですが、bin フォルダにおくとアプリケーションドメインの起動時に強制的に読みこまれちゃうみたいなので、動的にコードでロードしているなら bin フォルダ以外のどこかに置いてしまうというのも手かもしれません。


なお、個人的な経験では、bin フォルダにアセンブリがいっぱいあると、メモリ不足の例外が出やすくなるような気がします。たしか数百個あたりから挙動がおかしくなっていたように記憶していますので、できればまとめた方がいいんじゃないかなぁと思います。



hope it helps
D, an alchemist.
nodera
大ベテラン
会議室デビュー日: 2003/09/08
投稿数: 200
投稿日時: 2005-06-20 14:00
こんにちは。

>ASP.NET ワーカープロセス内部には、各アプリケーションごとにアプリケーションドメインが
>作られているようですので
ごめんなさい、自分嘘書いちゃいましたね。。。(推測でモノいうものではなかった^^;)
自分も試してみたら、プロセスの再起動ではなく、アプリケーションドメインの再構築のようで、DLLが多くなればなるほど、起動に時間を要してました。
これって、DLLを読み込んでるのかな。。。?
回避方法は、D, an alchemistさんの云われるように、binフォルダ以外から読み込んだほうがいいかもしれません。

あさべー
会議室デビュー日: 2005/06/03
投稿数: 11
投稿日時: 2005-06-20 16:51
Webサービスのbinフォルダ以外にDLLを配置し
そこからロードするようにすることで全て解決しました。

引用:
なお、個人的な経験では、bin フォルダにアセンブリがいっぱいあると、メモリ不足の例外が出やすくなるような気がします。たしか数百個あたりから挙動がおかしくなっていたように記憶していますので、できればまとめた方がいいんじゃないかなぁと思います。



なお、DLLの数の問題ですが、
1000個のDLLを何個かずつまとめてみようとも思ったのですが
binフォルダじゃなければおそらく大丈夫かなと思いますので
とりあえずこのままで様子を見てみます。

皆さんいろいろありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)