背景
我正在比较在IIS7下运行的NancyFx和ServiceStack.NET的性能(在Windows7主机上测试)。两者都在本地疯狂地快速测试每个框架处理的10,000+请求/秒,ServiceStack的速度要快20%左右。
我遇到的问题是,ASP.NET似乎正在缓存来自HttpHandler的每个唯一URI请求的响应,这很快就导致了巨大的内存压力(3+ GC),并使垃圾收集器超负荷工作(GC消耗了大约25%的时间)。到目前为止,我还无法禁用对象的缓存和构建,我正在寻找有关如何禁用此行为的建议。
详细信息
request循环的基本流程如下:
for i = 1..100000:
string uri = http://localhost/users/{i}
Http.Get(uri)
响应是一个简单的JSON对象,格式为{ UserID: n }。
我已经破解了打开的WinDBG,对于每个请求,都有:
System.Web.FileChangeEventHandler
System.Web.Configuration.MapPathCacheInfos
System.Web.CachedPathDatas
System.Web.Caching.CacheDependencys
System.Web.Caching.CacheEntrys
显然,这些缓存项使我相信这是一个缓存膨胀问题(我希望摆脱150,000个不可用的对象!)。
我到目前为止所尝试的
在IIS 'HTTP Resonse Headers‘中,将’'immediately'.
web.config中的
Prevent many different MVC URLs from filling ASP.NET Cache。设置
<cache percentagePhysicalMemoryUsedLimit="1" privateBytesPollTime="00:00:01"/>
提供了帮助,但即使使用这些非常激进的设置,内存使用量也会迅速上升到2.5 4GB(而不是4 4GB)。理想情况下,这些对象从一开始就不会被创建。如果做不到这一点,我可能会求助于一种老套的解决方案:使用反射来清除缓存(所有这些条目都是“私有的”,并且在迭代公共缓存时不会被枚举)。
发布于 2011-12-24 01:24:09
我认为这不是缓存的问题,而是“高内存利用率”的问题。
两件事,
如果您使用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,它不是一次性的,如果您连续调用,它可能会挂起更长的时间。
其次,如果您连续调用外部服务器,我会在每次调用之间设置延迟。这将提供一些喘息的空间,因为您的处理器处理for循环的速度将远远快于网络响应的时间(并且只会使请求排队,从而减慢实际正在处理的请求的速度)。
System.Threading.Thread.Sleep(250);
显然,最好的解决方案是使用您想要检索的用户列表进行一次调用,并只处理一个the请求/响应。
发布于 2013-02-01 05:45:50
对其他有同样问题的人的延迟响应:
这是一个已知的问题:KB 2504047
发生此问题的原因是,尝试访问相同资源的唯一请求将作为MapPathCacheInfo objects缓存10分钟。
当对象缓存10分钟时,W3wp.exe进程的内存消耗会显著增加。
您可以下载修补程序here
发布于 2011-08-04 09:51:15
确保IsReusable属性设置为false,这样IIS就不会重用相同的请求进程来处理请求。
https://stackoverflow.com/questions/6863586
复制相似问题