C#编程时应注意的性能处理

GC堆回收

那么除了经过new对象而达到代的阈(临界)值时,还有什么可以致使垃圾堆进行垃圾回收呢? 还可能windows报告内存不足、CLR卸载AppDomain、CLR关闭等其它特殊状况。算法

或者,咱们还能够本身经过代码调用。windows

.NET有GC来帮助开发人员管理内存,而且版本也在不断迭代。GC帮咱们托管内存,但仍然提供了System.GC类让开发人员可以轻微的协助管理。 这其中有一个能够清理内存的方法(并无提供清理某个对象的方法):GC.Collect方法,能够对全部或指定代进行即时垃圾回收(若是想调试,需在release模式下才有效果)。这个方法尽可能别用,由于它会扰乱代与代间的秩序,从而让低代的垃圾对象跑到生命周期长的高代中。服务器

GC还提供了,判断当前对象所处代数、判断指定代数经历了多少次垃圾回收、获取已在托管堆中分配的字节数这样的三个方法,咱们能够从这3个方法简单的了解托管堆的状况。网络

托管世界的内存不须要咱们打理,咱们没法从代码中得知具体的托管对象的大小,你若是想追求对内存最细微的控制,显然C#并不适合你,不过相似于有关内存把控的这部分功能模块,咱们能够经过非托管语言来编写,而后经过.NET平台的P/Invoke或COM技术(微软为CLR定义了COM接口并在注册表中注册)来调用。并发

像FCL中的源码,不少涉及到操做系统的诸如 文件句柄、网络链接等外部extren的底层方法都是非托管语言编写的,对于这些非托管模块所占用的资源,咱们能够经过隐式调用析构函数(Finalize)或者显式调用的Dispose方法经过在方法内部写上非托管提供的释放方法来进行释放。app

像文中示例的socket就将释放资源的方法写入Dispose中,析构函数和Close方法均调用Dispose方法以此完成释放。事实上,在FCL中的使用了非托管资源的类大多都遵循IDispose模式。而若是你没有释放非托管资源直接退出程序,那么操做系统会帮你释放该程序所占的内存的。socket

 垃圾回收对性能的影响

还有一点,垃圾回收是对性能有影响的。
GC虽然有不少优化策略,但总之,只要当它开始回收垃圾的时候,为了防止线程在CLR检查期间对对象更改状态,因此CLR会暂停进程中的几乎全部线程(因此线程太多也会影响GC时间),而暂停的时间就是应用程序卡死的时间,为此,对于具体的处理细节,GC提供了2种配置模式让咱们选择。函数

第一种为:单CPU的工做站模式,专为单CPU处理器定作。这种模式会采用一系列策略来尽量减小GC回收中的暂停时间。 
而工做站模式又分为并发(或后台)与不并发两种,并发模式表现为响应时间快速,不并发模式表现为高吞吐量。高并发

第二种为:多CPU的服务器模式,它会为每一个CPU都运行一个GC回收线程,经过并行算法来使线程能真正同时工做,从而得到性能的提高。性能

咱们能够经过在Config文件中更改配置来修改GC模式,若是没有进行配置,那么应用程序老是默认为单CPU的工做站的并发模式,而且若是机器为单CPU的话,那么配置服务器模式则无效。

若是在工做站模式中想禁用并发模式,则应该在config中运行时节点添加 <gcConcurrent enabled="false" /> 
若是想更改至服务器模式,则能够添加 <gcServer enabled="true" />。

复制代码
 <configuration>
        <runtime>
            <!--<gcConcurrent enabled="true|false"/>-->
            <!--<gcServer enabled="true|false"/>-->
        </runtime>
</configuration>
复制代码

gcConcurrent: https://docs.microsoft.com/zh-cn/dotnet/framework/configure-apps/file-schema/runtime/gcconcurrent-element 
gcServer: https://docs.microsoft.com/zh-cn/dotnet/framework/configure-apps/file-schema/runtime/gcserver-element

  性能建议

虽然咱们能够选择适合的GC工做模式来改善垃圾回收时的表现,但在实际开发中咱们更应该注意减小没必要要的内存开销。

几个建议是,减换须要建立大量的临时变量的模式、考虑对象池、大对象使用懒加载、对固定容量的集合指定长度、注意字符串操做、注意高频率的隐式装箱操做、延迟查询、对于不须要面向对象特性的类用static、须要高性能操做的算法改用外部组件实现(p/invoke、com)、减小throw次数、注意匿名函数捕获的外部对象将延长生命周期、能够阅读GC相关运行时配置在高并发场景注意变换GC模式...

对于.NET中改善性能可延伸阅读 https://msdn.microsoft.com/zh-cn/library/ms973838.aspx 、 https://msdn.microsoft.com/library/ms973839.aspx

相关文章
相关标签/搜索