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 ...
随机推荐
- 作为新手在学习SSM+Easyui过程中遇到一系列问题
对于初学SSM来说,如果不熟悉SSM中SpringMVC对数据处理,会造成很大的困扰, SSM中对前台页面放在WEB-INF下,对于读取外部信息,例如导入easyui的js文件.以及不能直接进行跳转. ...
- UDP聊天工具的实现
利用TIdUDPClient; TIdUDPServer; 实现聊天,其实很不爽,没有解决中文乱码问题,以后补充吧! 代码如下: unit Unit1; interface uses ...
- hdu4003详解(树形dp+多组背包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4003 Find Metal Mineral Time Limit: 2000/1000 MS (Jav ...
- 软件测试:第二次作业(JUnit单元测试方法)
一.JUnit是什么? JUnit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework).JUnit测试是程序员测试, ...
- Java语法基础学习DayTwenty(反射机制续)
一.Java动态代理 1.代理设计模式的原理 使用一个代理将对象包装起来, 然后用该代理对象取代原始对象. 任何对原始对象的调用都要通过代理. 代理对象决定是否以及何时将方法调用转到原始对象上. 2. ...
- undo系统参数详解
查看与undo相关的系统参数 1.undo_management 有两个参数值:auto.manual(默认) manual:系统启动后使用rollback segment存储undo信息: auto ...
- 使用EFCore处理并发冲突
一.首先添加并发处理标记 在需要进行并发处理的类中添加版本号,并在版本号上使用[Timestamp]标记: public class Department { public int Id { get; ...
- linux安装openssl
1.简介 给网站配置http2发现openssl版本不够,只能靠升级openssl了,shell让安装不再麻烦. 系统环境 centos 7.4 64位 安装 openssl1.1.1a版本 2.查看 ...
- Struts2配合layui多文件上传--下载
先说上传: 前台上传文件的js代码: var demoListView = $('#demoList') ,uploadListIns = upload.render({ elem: '#testLi ...
- 【转】Android-Input 键盘设备
https://source.android.com/devices/input/keyboard-devices 键盘设备 Android 支持各种键盘设备,包括特殊功能小键盘(音量和电源控制),紧 ...