前言:本章主要详细的讲述如何因内存问题而致使的性能问题,不少的时候都是深刻.NET内核进行分析,而后给出解决方案,同时,本系列的其余文章,也争取作到:深刻浅出。html
本篇是为后面的作个铺垫,并且比较的精彩。只有真正的理解了本篇,后面才能够顺利的走下去。编程
本篇的议题以下:缓存
内存问题概述(前篇)性能优化
托管资源优化(前篇)服务器
对象的生命周期(前篇)ide
对象的”代“(前篇)性能
大对象堆(LOH) (前篇)优化
CLR计数器的使用(前篇)htm
非托管资源优化对象
Session会话的优化
内存问题概述
和CPU同样,内存也是一个直接影响服务端性能的重要的硬件资源。
通常来讲,若是服务端内存不足,从致使如下两个问题产生:
1. 致使服务端把一些本来要写到内存中的数据,写到硬盘上面。这样不只仅加大了CPU和磁盘的I/O操做,同时也延长了读取这些数据的时间。
2. 阻止了一些缓存策略的使用。
对于内存不足,一直最快最直接的方式就是去买内存条加在服务器上面。可是这样存在一个隐患的问题就是:若是加了新的内存以后,服务端又面临内存不足的问题,咱们不可能无止境的加内存条,那么咱们就必须从站点自己来解决这个问题,例如从服务端的配置,对站点的代码进行分析,优化。
托管资源优化
对于托管资源,相信你们并不陌生了,简单的说就是:在C#的托管堆上面建立的资源,或者说经过new产生的对象。
在深刻讲解以前,咱们首先来看看”对象的生命周期”
对象的生命周期
当咱们用new关键字建立了一个对象的时候,这个对象就被分配到CRL托管堆上面。这个托管堆是在内存中的。并且这个分配对象空间的速度是很是的快的,由于每次都是在托管堆的最后面划出必定的空间来给这个对象,不用去堆上面需找合适大小的空间。
若是当托管堆准备为一个对象分配空间的时候,发现托管堆上面的空间过小了,不足以分配给这个新的对象,那么CLR就开始运行垃圾回收机制了。咱们知道:垃圾回收机制会把那些在托管堆上面没有了引用指向的那些对象都清理掉,同时也会把托管堆上面现存的对象进行压缩。
可是有一点须要清楚:若是此时进行了垃圾回收的时候,清除了一些没有用的对象,可是只有在下一次来回收进行的时候,上次垃圾回收清除的对象才真正的从内存中消除(此时,还有一些“对象复苏“等话题就不在赘述)。
下面就来说述一些垃圾回收的话题。
对象的“代”
在CLR进行垃圾回收的时候,垃圾回收器回去托管堆上面去检查对象是否能够被回收,这个检查过程是很是消耗资源的。为了不每次垃圾回收都要便利托管堆上面的全部对象,CLR给把托管堆上面的对象用”代”来划分,例如,第一代,第二代。而后每次便利扫描托管堆的时候,就去扫描某一个”代”中的对象,这样性能就好点。
在托管堆上面,能够把对象分为三个”代”:0代,1代,2代,仅此这三个代。每一个对象都是从0×××始的。一个对象每经历一次垃圾回收,而且这个对象还在使用中,那么这个对象的“代“就会增长1代。例如,若是在0代的对象,经历了一次垃圾回收以后,他的代就是1代,若是是1代的对象,最后就会变为2代。若是对象自己已是2代了,无论经历多少次垃圾回收(若是对象一直在使用),那么这个对象仍是2代。
在CLR垃圾回收中有句话要记得:” ’代’数越大,被回收的可能性就越小”。并且一些性能优化就是根据这个进行的。
每次CLR在进行垃圾回收的时候,都会优先的去扫描第0代的对象,因此,一些新的,临时使用的对象能够被马上的清除。相比而言,垃圾回收器扫描第1代对象的频率就没有第0代强,扫描第2代对象的频率就更低了。因此说:对象存活的时间越长,就越难被回收,并且一直占据CLR的内存资源。
还有有点须要注意的就是:若是CLR决定要扫描了第1代了,同时也用扫描第0代的对象,同时若是,CLR扫描第2代对象,那么第0代,第1代对象都会被扫描。
因此,从这里能够得出:咱们尽可能避免把本来须要马上回收的的对象变为长期存活的对象。通俗点说就是:若是一个对象原本已经存活在0代的,而后用完就回收的,咱们不要让这个对象一直存活到第1代,甚至第2代。在编程上面基本就是这样的实现思路:尽量晚的实例化对象,尽量早的释放对象。
大对象堆(Large Objecet Heap)
咱们以前讲述了”堆”的一些话题,CLR除了上面的通常的堆(通常的new对象分配空间的那个堆),CLR中还存在另外的一个堆:专门用来放置那些大于了85k的对象的堆,大对象堆。
若是new一个对象的时候,这个对象的大小超过了85k,那么CLR就会把这个对象放在LOH上面。若是此时LOH的空间不足了,那么CLR就会启动垃圾回收器去扫描LOH堆和那个通常堆上面的第2代对象,咱们以前说过,若是扫描第2代对象,就同时扫描第1代,第0代,那么实际至关于扫描了整个托管堆,性能影响可想而知。
并且不想以前那个通常堆,在LOH上面的对象被垃圾回收器回收以后,上面的大对象是不会被压缩的,那么LOH这个堆上面就可能存在一些”空间碎片”,而后分配新的大对象的时候,就要找空间,甚至进行碎片的整理,你们能够联想一下咱们电脑的磁盘碎片整理。
原文连接:http://www.cnblogs.com/yanyangtian/archive/2011/02/17/1956768.html