快捷搜索:  as  2018  FtCWSyGV  С˵  test  xxx  Ψһ  w3viyKQx

澳门新葡新京返水_龟发之家论坛



谈谈近来优化一个网站项目的履历,首先说一下背景环境:

1) 在页面后台代码中我们把页面上大年夜部分的HTML都应用字符串来拼接天生然后直接赋值给LiteralControl。

2) 网站CPU很高,基础都在80%阁下,纵然应用了StringBuilder来拼接字符串机能也不抱负。

3) 为了改良机能,把全部字符串保存在memcached中,机能照样不抱负。

在对照了这个网站和其它网站办事器上相关机能监视器指标后发明有一个参数分外显眼:

便是此中的每秒分配字节数,这个机能对照差的网站每秒分配2GB的内存(而且必要留意因为机能监视器是每秒更新一下,对付一个异常康健的网站这个值应该常常看到是0才对)!而其它一些网站只分配200M阁下的内存。办事器配备4G内存,而每秒分配2G内存,我想垃圾收受接收器必然必要赓续运行来收受接收这些内存。察看%Time in GC可以发明,这个值不停在10%阁下,也便是说上次收受接收到此次收受接收距离10秒的话,此次垃圾收受接收1秒,因为收受接收的光阴相对固定,那么这个值可以反应收受接收的频繁度。

知道了这个要点就知道了偏向,在项目中找可能的问题点:

1) 是否分配了大年夜量临时的小工具

2) 是否分配了数量不多但对照大年夜的大年夜工具

在经历了一番查找之后,发明一个对照大年夜的问题,虽然应用了memcached来缓存全部页面的HTML,然则在输出之前居然进行了几回string的WordStr操作,这样就孕育发生了几个大年夜的字符串,我们来做一个实验模拟这种场景:

public partial class _Default : System.Web.UI.Page

{

static string tem澳门新葡新京返水plate;

protected void Page_Load(object sender, EventArgs e)

{

if (template == null)

{

StringBuilder sb = new StringBuilder();

for (int i = 0; i "1234567890");

template = sb.ToString();

}

Stopwatch sw = Stopwatch.StartNew();

for (int i = 0; i long mem1 = GC.GetTotalMemory(false);

string s = template + i;

long mem2 = GC.GetTotalMemory(false);

Response.Write((mem2 - mem1).ToString("N0"));

Response.Write("

");

GC.KeepAlive(s);

}

for (int i = 0; i double d = Math.Sqrt(i);

}

Thread.Sleep(30);

Response.Write(sw.ElapsedMilliseconds);

}

}

在这段代码中:

1) 我们首先应用一个静态变量模拟缓存中的待澳门新葡新京返水输出的HTML

2) 我们中心的一段代码测算一下这个字符串占用的内存空间

3) 随后我们做了一些耗损CPU的运算操作来模拟页面的一些谋略

4) 然后休眠一段光阴

4) 着末我们输出了页面履行光阴

我们这么做的目的是模拟一个对照“正常的”ASP.NET页面必要做的一些事情:

1) 内存上的分配

2) 一些谋略

3) 涉及到IO造访的一些等待

来看看输出结果:

这里可以看到,我们这个字符串占用差不多200K的字节,字符串是字符数组,CLR中字符采纳Unicode双字节存储,是以10万长度的字符串占用200千字节,并且也可以看到这个页面履行光阴30毫秒,差不多是一个正常aspx页面的光阴,而200K不到的字符串也差不多相称于这个页面的HTML片段,现在我们来改一下此中的一段代码模拟优化提高行的WordStr操作带来的几个大年夜字符串:

for (int i = 0; i //long mem1 = GC.GetTotalMemory(false);

string s = template + i;

//long mem2 = GC.GetTotalMemory(false);

//Response.Write((mem2 - mem1).ToString("N0"));

//Response.Write("

");

//GC.KeepAlive(s);

}

然后应用IDE自带压力测试1000常量用户来测试这个页面:

可以看到每秒分配了跨越400M字节(这和我们线上情况比还差点终究哀求少),CPU占用基础在120-160阁下(双核),我们去掉落每秒分配内存这个数值,来看看垃圾收受接收频率和CPU占用两个值的澳门新葡新京返水图表:

可以看到血色的CPU颠簸基础和蓝色的垃圾收受接收颠簸维持同等(这里不太准确的别的一个缘故原由是压力测试客户端运行于本机,而为w3wp关澳门新葡新京返水联2个处置惩罚器)!为什么说垃圾收受接收会带来CPU的颠簸,从理论上来说有以下缘故原由:

1) 垃圾收受接收的时刻会暂时挂起所有线程,然后GC会检测扫描每一个线程栈上可收受接收工具,然后会移动工具,并且从新设置工具指针,这全部历程首先是耗损CPU的

2) 而且在这个历程之后规复线程履行,这个时刻CPU每每会引起一个高峰由于已经有更多的哀求等待了

我们把Math.Sqrt这段代码注释掉落并且把w3wp和VSTestHost关联到不合的处置惩罚器来看看对付CPU谋略很少的页面,上图更显着的比较:

这阐明垃圾收澳门新葡新京返水受接收切实着实会占用很多CPU资本,但这只是一部分,着实我感觉网站的CPU压力来自于几个地方:

1) 便是大年夜量的内存分配带来的垃圾收受接收所占用的CPU,对付ASP.NET框架内部的很多行径无法节制,然则可以在代码中只管即便避免在堆上孕育发生很多不需要的工具

2) 是实际的CPU运算,不涉及IO的运算,这些可以经由过程改善算法来优化,然则优化对照有限

3) 是IO操作这块,数据量的若干很关键,还有要斟酌memcached等外部缓存工具序列化反序列化的耗损

4) 虽然很多IO操作不占用CPU资本,线程处于休眠状态,然则很多时刻着实是依托新线程进行的,带来的便是线程切换和线程创建耗损的耗损,这一块可以经由过程合理应用多线程来优化

发清楚明了这个问题之后优化就很简单了,把WordStr操作放到memcached的Set操作之前,掏出之后不孕育发生过多大年夜字符串,把for轮回改为一次,再来看一下:

此次内存分配显着少了很多,CPU降下来了,降的不多,但从压力测试监视器中看到页面履行匀称光阴从5秒变为3秒了,每秒匀称哀求数从170到了200(最高从200到了300)。在这里要阐明一点很多时刻网站的机能优化不能光看CPU还要比较优化前后网站的负载,由于在优化之后页面履行光阴低落了,负载量就增大年夜了CPU耗损也随之增大年夜。并且可以看到垃圾收受接收频率的缩短很显着,从经久在30%到几十秒一次30%。

着末想弥补几点:

1) 有的时刻我们会应用GC.GetTotalMemory(true); 来获得垃圾收受接收之后内存分配数,类似这样涉及到垃圾收受接收的代码在项目上线后切切不能呈现,否则很可能会% Time in GC达到80%以上大年夜量占用CPU。

2) 对付放在缓存中的工具我们每每会感觉机能获得保障大年夜量去应用,着实缓存实现的只是把创造这个工具历程的光阴转化为空间,而在拿到这个工具之后再进行很多运算带来的大年夜量空间始终会进行垃圾收受接收。做网站和做利用法度榜样不一样,一个操作假如申请200K堆内存,一个页面履行这个操作10次,一秒200多个哀求,大年夜家可以自己算一下匀称每秒必要分配若干内存,这个数值是相称可骇的,网站是一个多线程的情况,我们对内存的应用要斟酌更多。

转自:http://www.cnblogs.com/lovecindywang/archive/2010/03/10/1682344.html

您可能还会对下面的文章感兴趣: