我们有一个用大量字符串连接实现的大型系统——它无处不在。
我们编写了一个快速页面,在循环中连接字符串。这在我们的 dev boxen(调试关闭)和我们的测试虚拟机上运行 3.3 秒。但是在生产(IIS7)上它运行时间为 15.7 秒。
任何人都可以建议我们可以查看服务器端(IIS 设置、内存设置等)来解决这个问题吗?
仅供参考 - 服务器有大量可用内存和可用 CPU 周期 - 所以它不是资源问题。 重写所有代码以使用 string.Join 或 StringBuilder 不在预算之内。
这会在内存中创建许多微小的字符串对象,这些对象需要稍后由垃圾收集器收集。将其替换为
var sMain = new StringBuilder();
while (something)
{
sMain.Append(sStringSub);
// ...
}
// Call sMain.ToString() when you need the whole string
不敢相信我是第一个推荐RedGates Profiling Tools的人。
这将告诉您究竟是什么在服务器上与开发 PC 上花费了这么多时间。
字符串是存储在托管堆上的引用类型,因此受垃圾回收的约束。GC 将在 GC 第一次检测到它无法释放内存时将您的字符串提升几代(0,1,2)。如果您查看CLR Profiler,我敢打赌您会看到分配给第 2 代的大量字符串。
重写所有代码以使用 string.Join 或 StringBuilder 不在预算之内。
它是否在预算内并不重要。如果一个应用程序需要 15 秒来响应,那么没有人会想要使用它,你也不会赚钱。你将不得不改变一些东西。
如果没有 Profiler 的踪迹,它就像在黑暗中开枪……我最好的猜测是开发 PC 有一个 SSD。
即使字符串是不可变的,并且很大一部分内存可能是指已连接的字符串,但 GC 无法收集。我仍然不认为这是一个内存问题,我敢打赌它与 I/O 有关,但分析器跟踪会确认。
将您的开发箱上的网站设置与您的生产箱不同。有很多事情可能会导致不同,从工作线程数到最大内存大小。如果超过这些阈值,IIS 将回收工作人员。
另外,您在开发盒上使用的是 IIS 还是 Cassini?
检查您的应用程序是否未在调试模式下运行。