バックグラウンド
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を開いてクラックしました。リクエストごとに次のものがあります。
- 1
System.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 と比較して)。これらのオブジェクトが最初から作成されないことが理想的です。それができない場合は、リフレクションを使用してキャッシュをクリアするというハックな解決策に頼るかもしれません (これらのエントリはすべて「プライベート」であり、パブリック キャッシュを反復処理するときに列挙されません)。