19

バックグラウンド

IIS 7 で実行されている NancyFx と ServiceStack.NET のパフォーマンスを比較している最中です (Windows 7 ホストでのテスト)。どちらも非常に高速です。各フレームワークをローカルでテストすると、毎秒 10,000 以上のリクエストが処理され、ServiceStack は約 20% 高速です。

私が直面している問題は、ASP.NET が HttpHandler からの一意の URI 要求ごとの応答をキャッシュしているように見え、すぐに大量のメモリ負荷 (3 GB 以上) が発生し、ガベージ コレクターが過負荷になることです (約 25% の時間が消費されます)。 GC)。これまでのところ、オブジェクトのキャッシングとビルドアップを無効にすることができませんでした。この動作を無効にする方法についての提案を探しています。

詳細

リクエストループは基本的に次のとおりです。

for i = 1..100000:
    string uri = http://localhost/users/{i}
    Http.Get(uri)

応答は、{ UserID: n } の形式の単純な JSON オブジェクトです。

私はWinDBGを開いてクラックしました。リクエストごとに次のものがあります。

  • 1System.Web.FileChangeEventHandler
  • System.Web.Configuration.MapPathCacheInfos
  • System.Web.CachedPathDatas
  • System.Web.Caching.CacheDependencys
  • System.Web.Caching.CacheEntrys

明らかに、これらのキャッシュ アイテムが原因で、キャッシュの肥大化の問題であると思われます (150,000 個の使用できないオブジェクトを取り除きたいです!)。

これまでに試したこと

  • IIS の「HTTP 応答ヘッダー」で、「Web コンテンツの期限切れ」を「即時」に設定します。
  • web.config で

    <system.web>
     <caching>
        <outputCache enableOutputCache="false" enableFragmentCache="false"/>
      </caching>
    </system.web>
    
  • また、web.config (およびポリシーのさまざまなバリエーション (なしを含む)) にも含まれます。

    <caching enabled="false" enableKernelCache="false">
      <profiles>
        <add policy="DontCache" kernelCachePolicy="DontCache" extension="*/>
      </profiles>
    </caching>
    
  • フレームワークのソース コードを調べて、ASP.NET キャッシュを使用する "機能" が組み込まれているかどうかを確認しました。キャッシュ ヘルパーはありますが、フレームワーク自体に限定されており、ASP.NET キャッシュを利用していないようです。

更新 #1

リフレクターを調べてみると、 の値UrlMetadataSlidingExpirationをゼロに設定すると、スループットが 50% 低下する代わりに、過剰なメモリ使用量の大部分が解消されることがわかりました (FileAuthorizationModule クラスは FileSecurityDescriptors をキャッシュします。UrlMetadataSlidingExpirationは非ゼロです)。

これを行うには、web.config を更新し、以下を に配置します。

<hostingEnvironment urlMetadataSlidingExpiration="00:00:00"/>

可能であれば、FileAuthorizationModule の実行を完全に無効にして、それが役立つかどうかを確認します。ただし、ASP.NET は依然として 2*NMapPathCacheInfoおよびCacheEntryオブジェクトを生成しているため、メモリは依然として消費されていますが、その速度ははるかに遅くなります。

アップデート #2

問題の残りの半分は、ここで説明されているのと同じ問題です: Prevent many different MVC URLs from fill ASP.NET Cache . 設定

<cache percentagePhysicalMemoryUsedLimit="1" privateBytesPollTime="00:00:01"/> 役に立ちますが、これらの非常に積極的な設定でも、メモリ使用量はすぐに 2.5GB に上昇します (4GB と比較して)。これらのオブジェクトが最初から作成されないことが理想的です。それができない場合は、リフレクションを使用してキャッシュをクリアするというハックな解決策に頼るかもしれません (これらのエントリはすべて「プライベート」であり、パブリック キャッシュを反復処理するときに列挙されません)。

4

3 に答える 3

2

同じ問題に苦しんでいる他の人への遅い応答:

これは既知の問題です: KB 2504047

この問題は、同じリソースにアクセスしようとする一意の要求がMapPathCacheInfo オブジェクトとして 10 分間キャッシュされるために発生します。

オブジェクトが 10 分間キャッシュされる間、W3wp.exe プロセスのメモリ消費量が大幅に増加します。

ホットフィックスはこちらからダウンロードできます

于 2013-01-31T21:45:50.427 に答える
2

これはキャッシングの問題ではなく、「高いメモリ使用率」の問題だと思います。

2つのこと、

IDisposable フレンドリ オブジェクトを使用する場合 (「using」キーワードを使用できるオブジェクトを試してください)。これにより、オブジェクトを遅かれ早かれ破棄できるようになり、長期的にはガベージ コレクターへの負担が軽減されます。

for (int i = 0; i < 10000; i++) {
    using (System.Net.WebClient c = new System.Net.WebClient()) {
        System.IO.Stream stream = c.OpenRead(String.Format("http://url.com/{0}", i));

    }
}

あなたの疑似コードから、使い捨てではない System.Net.WebHttpRequest を使用していると推測できます。

第 2 に、外部サーバーに対して連続して呼び出しを行っている場合は、呼び出しごとに遅延を設けます。これにより、ネットワークが応答する時間よりもプロセッサが for ループをはるかに高速に処理するため、息抜きの余地が生まれます (そして、要求をキューに入れ続け、実際に処理される速度を遅くします)。

System.Threading.Thread.Sleep(250);

明らかに、最良の解決策は、取得したいユーザーのリストを使用して単一の呼び出しを行い、1 つの Web 要求/応答を処理することです。

于 2011-12-23T17:24:08.770 に答える
1

IsReusable プロパティが false に設定されていることを確認して、IIS が同じ要求プロセスを再利用して要求を処理しないようにします。

http://support.microsoft.com/kb/308001

于 2011-08-04T01:51:15.133 に答える