本地ASP.NET MVC突然变得非常缓慢;加载时间> 1分钟

9
在过去的几周中,我在浏览本地托管的ASP.NET 3.5 MVC Web应用程序(C#)时遭遇了突然而显著的性能下降。给定页面的加载时间平均为20秒(无论内容如何);启动通常超过一分钟。这些应用程序在生产甚至测试系统上运行速度很快(测试系统与我的开发环境相当)。
我正在运行IIS 6.0、VS2008、Vista Ultimate、SQL2005、.NET 3.5、MVC 1.0,并使用VisualSVN 1.7。
我的SQL数据库是本地的,IPv6似乎不是原因。我在Firefox和IE8中以Debug模式之外的方式使用回环、机器名称和“localhost”进行浏览,每次都得到完全相同的结果(因此DNS似乎也不是问题)。
以下是我的dotTrace输出的屏幕截图。

http://www.glowfoto.com/static_image/28-100108L/3123/jpg/06/2010/img4/glowfoto

这个问题几乎让调试/测试任何Web应用程序变得不可能。非常感谢任何建议!
解决方案:完全重新安装Windows、IIS、Visual Studio等。虽然不是首选方案,但它起作用了。

这是另一个dotTrace性能分析的屏幕截图: http://www.glowfoto.com/static_image/28-080245L/5997/jpg/06/2010/img5/glowfoto - alan
2
乍一看,它看起来像是一个I/O问题(硬盘)。 - Chuck Conway
嗯...你肯定需要考虑使用不同的图像托管平台。我推荐imgur.com。 - Randolpho
这个Web应用程序使用的所有内容都托管在我的开发机器上。感谢您的评论!我正在尝试David的建议。欢迎其他建议! - alan
你是通过在VS中运行Web应用程序进行调试,还是已经在本地使用IIS进行设置?如果你还没有设置,我建议你使用IIS进行设置。当你需要查看断点时,可以使用“附加到进程”选项并附加到wpw3.exe。(勾选“显示所有用户的进程”框。) - Ryan
显示剩余3条评论
5个回答

1

我了解到,当事情失败接近于2的幂时,通常会出现“气味”...

考虑到:

在过去的几周中,我曾遭受突然而显著的性能下降

以及

AddExistingFile被调用了66,914次

我想知道是不是在文件数超过65,535时导致了性能下降...

其他需要考虑的可能性包括:

  • 所有的66,914个文件是否都在同一个目录中?如果是这样的话,那么访问大量的目录块...尝试进行硬盘碎片整理。如果它们分布在一堆目录中,那么访问的目录块将更多。

  • 您是否将所有文件存储在同一个列表中?您是否预设了该列表的容量,或者允许其自然缓慢“增长”?

  • 您是按照深度优先还是广度优先扫描文件?操作系统的缓存将有利于深度优先的性能。

更新14/7

澄清“您是否将所有文件存储在同一个列表中?”

像这个第一个例子一样天真的代码不会表现得最理想,因为它需要在列表增长时重新分配存储空间。
var myList = new List<int>();
for (int i=0; i<10000; i++)
{
    myList.Add(i);
}

如果你知道的话,使用特定容量初始化列表可以更高效地避免重新分配开销:

var myList = new List<int>(10000);  // Capacity is 10000
for (int i=0; i<10000; i++)
{
    myList.Add(i);
}

更新 15/7

原帖作者的评论:

这些 Web 应用程序并不是通过我的手动编程方式来探测硬盘上的文件。如果有任何递归文件扫描,那就是 VS 2008 在做。

进行文件扫描的不是 Visual Studio,而是你的 Web 应用程序。这在你发布的第一个分析器跟踪中可以清楚地看到——调用 System.Web.Hosting.HostingEnvironment.Initialize() 花费了 49 秒,其中大部分时间都花费在了 66,914 次调用 AddExistingFile() 上。特别是,读取属性 CreationTimeUTC 几乎占据了所有时间。

这种扫描不会是随机的——它要么是应用程序配置的结果,要么是文件位于你的 Web 应用程序文件树中。找到这些文件,你就会知道性能问题的原因。


如果在加载页面时需要多次访问目录中的每个文件,那么系统设计可能存在问题。此外,当文件数量增加时,他将在生产环境中遇到此问题。+1 - Shiraz Bhaiji
@Bevan 你能推荐一个高质量的碎片整理软件吗?我使用默认的Windows碎片整理工具没有效果。你说的“将所有文件存储在同一列表中”是什么意思?这些Web应用程序不会通过我的手编程探测硬盘上的文件。如果有任何递归文件扫描,那就是由VS 2008完成的。 - alan
@Shiraz,我有一个类似的测试环境和第二个开发环境,两者都没有遇到这个问题。 - alan
我使用了MyDefrag,但性能没有改善。有什么建议可以定位这69k+调用是从哪里来的吗?我很困惑,可能是最近添加的一些汇编代码。然而,我无法确定是哪个汇编代码。 - alan
来自 SysInternals 的 Process Monitor 可以显示文件系统活动,这应该会指引您朝正确的方向前进。 - Bevan
显示剩余2条评论

1

那个分析器输出中的大红旗显然是AddDirectory被调用了408次,而AddExistingFile被调用了66,914次?

你能否确认一下你的MVC应用程序根目录下没有大量的目录和文件?因为看起来框架正在忙于尝试确定启动时需要构建哪些文件(或添加监视器)。

[我对MVC不熟悉,所以也许这不是正在发生的事情,但是一个名为“AddExistingFile”的函数被调用了67k次确实有点不对劲]。


实际上,在解决方案的根目录下有53308个文件和1684个文件夹。对于特定的项目,有27029个文件和445个文件夹。在处理相关项目时,我已经卸载了所有其他项目,但它们运行速度仍然很慢。 - alan
我认为现在是考虑拆分项目的时候了。将类分组成逻辑单元,并将它们重构为单独的类库。请记住,即使您只更改项目中的一个文件,每个文件都必须重新编译。如果您拆分项目,只有更改的项目文件将被重新构建。当我这样做时,一个解决方案的典型构建时间从超过一分钟的构建时间变为2秒。此外,如果您有任何DBML,请始终将其放在自己的项目中,因为它们很大。 - Ryan
@Ryan 很遗憾,我没有权力将它们拆分开来;我只是一名初级开发人员。不过,我可以通过 "卸载项目"(Visual Studio 2008)实现相同的结果,从而可以将不相关的项目排除在构建之外。 - alan
@alan 你可以通过定义自己的构建配置来实现相同的结果。它们在“生成”>“配置管理器”菜单中。 - Ryan

0

尝试在新的Web文件夹中创建一个新的默认MVC2应用程序。构建并浏览它。如果新应用程序的加载时间正常,则可能是您的应用程序出了问题。如果不行,那么问题就超出了应用程序的范畴,您应该开始查看IIS配置、扩展、硬件、网络等。

在您的应用程序中,备份您的Web配置文件,并使用新的默认web.config文件开始。这将禁用您安装的任何扩展或处理程序。如果这可以解决您的加载时间问题,请逐渐将旧的web.config文件中的内容添加到新的文件中,直到问题重新出现,并以此方式隔离有问题的项目。

我称之为“二分搜索”调试。虽然有点繁琐,但实际上非常快速,而且很可能会在我们陷入“但它应该工作!”模式时识别出问题。

更新 一个想法:为了排除IIS配置问题,请尝试在Cassini/内置开发服务器下运行站点。


谢谢你的建议,David。新的MVC项目加载比较快。然而,在针对该项目使用默认web.config启动之后,即使只重新添加了最小的部分,也会出现相同的缓慢情况。 - alan
嗯,好吧,至少这告诉你在你的应用程序中有一些导致问题的东西。你的 global.asax.cs 有什么新的内容吗?另外,你的 IIS 文件夹是本地的,对吗? - 3Dave
我必须弄清楚如何运行Cassini而不是IIS,但我会尝试一下。我的Global.asax没有任何新内容。是的,IIS文件夹直接从我的项目Bin中运行。 - alan
@Alan,既然你有一个运行正确的应用程序和一个不正常的应用程序,我建议你从一个应用程序中移动部分到另一个应用程序。我知道这在任何规模的应用程序中都是非常麻烦的,但至少你可以取得进展。此外,你确定没有吞掉可能让你知道问题所在的异常吗?例如数据库不可用等? - 3Dave
我尝试浏览localhost:23423,但收到了页面未找到的错误;这很合理,因为它只应该显示在443和80上。 - alan
显示剩余7条评论

0

你可以下载 Fiddler 来测量每个调用所需的时间并获取一些测量结果。

链接

这个视频可能会有所帮助...


谢谢您的建议,这与我发布的DotTrace输出有什么不同吗?它提供了调用的时间测量。在我投入下载、安装、登录和发布结果的过程之前,我需要知道这一点(我手头有很多项目)。 - alan
你可能不会在 Fidler 中看到太大的差异。但是,在视频中,你可以看到 Web 应用程序变慢,他们获取了堆栈转储,并能够分析应用程序变慢的线程。我建议你尝试这种方法。 - shookdiesel

0
解决方案是格式化并进行干净的 Vista、SQL Server 2005、Visual Studio 2008、IIS6 和整个软件包的安装。现在,我能够调试之前遇到问题的同一 Web 应用程序,而不会有任何后果。这让我相信问题出在上述某个安装中,并且可能由软件更新或添加软件加剧了该问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接