C#编程时应注意的性能处理
GC堆回收
那么除了通过new对象而达到代的阈(临界)值时,还有什么能够导致垃圾堆进行垃圾回收呢? 还可能windows报告内存不足、CLR卸载AppDomain、CLR关闭等其它特殊情况。
或者,我们还可以自己通过代码调用。
.NET有GC来帮助开发人员管理内存,并且版本也在不断迭代。GC帮我们托管内存,但仍然提供了System.GC类让开发人员能够轻微的协助管理。 这其中有一个可以清理内存的方法(并没有提供清理某个对象的方法):GC.Collect方法,可以对所有或指定代进行即时垃圾回收(如果想调试,需在release模式下才有效果)。这个方法尽量别用,因为它会扰乱代与代间的秩序,从而让低代的垃圾对象跑到生命周期长的高代中。
GC还提供了,判断当前对象所处代数、判断指定代数经历了多少次垃圾回收、获取已在托管堆中分配的字节数这样的三个方法,我们可以从这3个方法简单的了解托管堆的情况。
托管世界的内存不需要我们打理,我们无法从代码中得知具体的托管对象的大小,你如果想追求对内存最细微的控制,显然C#并不适合你,不过类似于有关内存把控的这部分功能模块,我们可以通过非托管语言来编写,然后通过.NET平台的P/Invoke或COM技术(微软为CLR定义了COM接口并在注册表中注册)来调用。
像FCL中的源码,很多涉及到操作系统的诸如 文件句柄、网络连接等外部extren的底层方法都是非托管语言编写的,对于这些非托管模块所占用的资源,我们可以通过隐式调用析构函数(Finalize)或者显式调用的Dispose方法通过在方法内部写上非托管提供的释放方法来进行释放。
像文中示例的socket就将释放资源的方法写入Dispose中,析构函数和Close方法均调用Dispose方法以此完成释放。事实上,在FCL中的使用了非托管资源的类大多都遵循IDispose模式。而如果你没有释放非托管资源直接退出程序,那么操作系统会帮你释放该程序所占的内存的。
垃圾回收对性能的影响
还有一点,垃圾回收是对性能有影响的。
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
C#编程时应注意的性能处理的更多相关文章
- Access Violations 访问冲突(AVs)是Windows编程时发生的最麻烦的错误?
Access Violations<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office&qu ...
- 在做APP前端开发时应注意的一些问题
在做APP前端开发时应注意的一些问题 在整个app开发流程中,app前端开发是一个必不可少的环节,也是一个在app开发过程中重量级的角色.说到这,那么在app应用的前端开发中,又要注意什么问题呢?一. ...
- APP前端开发时应注意的一些问题
在做APP前端开发时应注意的一些问题 在整个app开发流程中,app前端开发是一个必不可少的环节,也是一个在app开发过程中重量级的角色.说到这,那么在app应用的前端开发中,又要注意什么问题呢?一. ...
- 对于使用progisp软件进行ISP编程时进入不了编程模式的解决方法
标题: 对于使用progisp软件进行ISP编程时无法进入编程模式的解决方法 作者: 梦幻之心星 347369787@QQ.com 标签: [progisp, 软件] 目录: 软件 日期: 2019- ...
- 模块化编程时,#include到底要放在哪里?
结合我自己的经验,谈一谈模块化编程时#include应该出现的位置.总结起来大体有二条规则: 一.规则1:只包含必要的头文件 看下面这个模块: ===foo.c==== #include <st ...
- 单片机中用c编程时头文件reg51.h及reg52.h解析
单片机中用c编程时头文件reg51.h及reg52.h解析 我们在用c语言编程是往往第一行就是reg51.h或者其他的自定义头文件,我们怎么样来理解呢? 1)“文件包含”处理. 程序的第一行是一个“文 ...
- unity, scene视图查看场景时应调成正交模式
scene视图查看场景时应调成正交模式,以避免稍微滑动滚轮就导致视角过远或过近.
- 编程时 对 用途这个字段定义时 不要用using 这个英文
编程时 对 用途这个字段定义时 不要用using 这个英文
- 用eclipse javaEE编程时,不管什么程序都会出现这个错误[SetContextPropertiesRule]{Context} Setting property 'source' to 'org.eclipse.jst.jee.server:bookstore' did not find
用eclipse javaEE编程时,不管什么程序都会出现这个错误[SetContextPropertiesRule]{Context} Setting property 'source' to 'o ...
随机推荐
- Problem 7: 10001st prime
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. ...
- Oracle学习DayTwo
一.创建表和管理表 1.表名和列名的命名规则 必须以字母开头必须在 1–30 个字符之间必须只能包含 A–Z, a–z, 0–9, _, $, 和 #必须不能和用户定义的其他对象重名必须不能是Orac ...
- tcp 与udp 的区别
1.TCP和UDP对比 TCP(Transmission Control Protocol)可靠的.面向连接的协议(eg:打电话).传输效率低全双工通信(发送缓存&接收缓存).面向字节流.使用 ...
- mysql5.7通过json类型替代关联表
学校表: 1 create table school( 2 `id` bigint unsigned primary key not null auto_increment, 3 `name` var ...
- PHP多进程引发的msyql连接数问题
PHP多进程引发的msyql连接数问题 业务中有一块采用了PHP的pcntl_fork多进程,希望能提高效率,但是在执行的时候数据库报错 PDO::prepare(): Premature end o ...
- IPhone微信H5用Video标签播放不了视频
H5用Video标签播放视频 视频在安卓上可以正常播放,在苹果上却不能播放. 因为用了文件服务站点,而且不支持断点下载 把文件服务改成支持断点下载即可 断点下载参考(C#)
- 《贝贝GO》服务条款
服务条款 一.服务条款的确认与接收 1.贝贝GO客户端软件(以下简称“本软件”)各项电子服务的所有权和运作权归属于“东莞市山水信息技术有限公司”(以下称“本公司”)所有,本软件提供的服务将完全按照其发 ...
- Labview学习笔记-条件结构的两个问题
数组:“创建数组控件“用于连接数组 输入端:数组+元素 或数组+数组 右键创建数组控件 在连接数组项上打钩或取消,改变连接的数组维度 簇:就是C语言中的结构体 簇和数组的转换 必须保证各元素数据类型一 ...
- ng2 配置端口号
ng2 默认端口号4200 若要配置,用两种方法 (1)可以使用以下命令 ng server --port 4201 (2)找到node_modules/angular-cli/lib/confi ...
- wpf 命令
上图为命令的 示例