![](https://img-blog.csdnimg.cn/20201014180756928.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
.net 核心机制
JasonJuly
这个作者很懒,什么都没留下…
展开
-
反射的性能
反射是相当强大的一个机制,它允许在运行时发现并使用编译时还补了解的类型或成员。但是,它有下面两个缺点。1,反射会造成编译时无法保证类型类型安全性。由于反射要严重依赖字符串,所以会丧失编译时的类型安全性。2,反射速度慢。使用反射时,类型或成员的名称在编译时未知;要用字符串名称标识每个类型及其成员,以便在运行时发现他们。也就是说,使用System.Reflection命名空间中的类型扫描程序集的元数据时,反射要不断地执行字符串搜索。通常,字符串搜索执行的是不区分大小写的比较,这会进一步影响速度。使用反射调原创 2020-12-13 20:29:43 · 1250 阅读 · 0 评论 -
程序集加载
JIT编译器将方法的IL代码编译成本地代码时,会查看IL代码中引用了哪些类型。在运行时,JIT编译器利用程序集的TypeRef和AssemblyRef元数据表来确定哪一个程序集定义了所引用的类型。在AssemblyRef元数据表的记录项中,包含了构成程序集强名称的各个部分。JIT编译器所获取所有这些部分——包括名称(无扩展名和路径)、版本、语言文化和公钥标记(public key token)——并把他们连接成一个字符串。然后,JIT编译器尝试将与该标识匹配的一个程序集加载到AppDomain中(如果还没有原创 2020-12-08 22:13:43 · 243 阅读 · 0 评论 -
.net AppDomain
CLR COM服务器初始化,会创建一个AppDomain 。 AppDomain是一组程序集的逻辑容器。CLR初始化时创建的第一个AppDomain称为默认AppDomain, 这个默认的AppDomain只有在Windows进程终止时才会被销毁。除了默认AppDomain, 正在使用非托管COM接口方法或托管类型方法的一个宿主还可指示CLR创建额外的AppDomain。 AppDomain唯一的作用就是进行隔离。下面总结了AppDomain的具体功能。1,一个AppDomain中的代码创建的对象不能由原创 2020-11-29 23:04:50 · 140 阅读 · 0 评论 -
.net 线程协作式取消
.net framework 提供了一个标准的取消操作模式。这个模式是协作式的,意味着你想取消的操作必须显式地支持取消。换言之,无论执行操作的代码,还是试图取消操作的代码,都必须使用本节提到的类型。对于长时间运行的计算限制操作来说,支持取消是一件很“棒”的事情。标准协作式取消模式,为了这取消这个操作,首先必须创建一个System.Threading.CancellationTokenSource 对象。这个对象包含了和怪取消相关的所有状态。构造好一个CancellationTokenSource 之后,可原创 2020-11-28 17:05:29 · 153 阅读 · 0 评论 -
.net 易失字段
internal sealed class ThreadSharingData{ private Int32 m_flag =0; private Int32 m_value =0; //由一个线程执行 public void Thread1() { // 注意:以下两行代码可以按相反的顺序执行 m_value =5; m_flag =1; } // 这个方法由另一个线程执行 public void Thread2() { // 注意:m_value 可能在m_fla原创 2020-11-26 21:54:54 · 67 阅读 · 0 评论 -
.net 线程执行上下文
每个线程都关联了一个执行上下文数据结构。执行上下文(execution context)包含的东西有安全设置(压缩栈,Thread的Principal 属性和windows身份)、宿主设置以及逻辑调用上下文数据的LogicSetData和LogicalGetData 方法。线程执行代码时,有的操作会受到线程的执行上下文设置的影响。理想情况下,每当一个线程使用另一个线程执行任务时,前者的执行上下文应该流向辅助线程。这就确保了辅助线程执行的任何操作使用的是相同的安全设置和宿主设置。还确保了初始线程的逻辑调用上下原创 2020-11-23 22:59:32 · 260 阅读 · 0 评论 -
.net CLR线程池
创建和销毁线程是一个昂贵的操作,要耗费大量的时间。另外太多会浪费内存资源。由于操作系统必须调度可运行的线程并执行上下文切换,所以太多的线程还有损于性能。为了改善这个情况,CLR包含了代码来管理他自己的线程池。可将线程池想象成一个线程集合。每CLR一个线程池;这个线程池由CLR控制的所有AppDomain共享。如果一个进程中加载了多个CLR, 那么每个CLR都有它自己的线程池。CLR初始化时,线程池中是没有线程的。在内部,线程池维护了一个操作请求的队列。应用程序想执行一个异步操作,就调用某个方法,将一个记录原创 2020-11-22 19:22:40 · 194 阅读 · 1 评论 -
.net 线程开销
对于每个线程中,都有以下要素:1,线程内核对象(thread kernel object) OS为系统中创建的每个线程都分配并初始化这种数据结构之一。在该数据结构中,包含一组对线程进行描述的属性。数据结构中还包含所谓的线程上下文(thread context)。上下文是一个内存块,其中包含了CPU的寄存器集合。windows在一台使用x86 CPU的计算机上运行是,线程上下文使用约700字节的内存。对于x64和IA64 CPU,上下文分别使用约1240字节和2500字节的内存。2,线程环境块(threa原创 2020-11-21 20:03:43 · 96 阅读 · 0 评论 -
.net 引用类型和值类型
CLR支持两种类型:引用类型和值类型。虽然FCL中大多数类型都是引用类型,但程序员用的最多的还是值类型。引用类型总是从托管堆上分配的,C#的new操作符会返回对象的内存地址——也就是指向对象数据的内存地址。使用引用类型时,必须注意到一些性能问题。首先考虑以下事实。1,内存必须从托管堆上分配。2,堆上分配的每个对象都有一些额外的成员,这些成员必须初始化。3,对象中的其他字节(为字段而设)总是设为零。4,从托管堆上分配一个对象时,可能强制执行一次垃圾收集操作。如果所有类型都是引用类型,应用程序的性能将原创 2020-11-06 23:04:05 · 102 阅读 · 0 评论 -
.net 使用CriticalFinalizerObject 类型确保终结
为了简化编程,System.Runtime.ConstrainedExecution 命名空间定义了一个CriticalFinalizerObject类,其形式如下:public abstract class CriticalFinalizerObject{ protected CriticalFinalizerObject(){ /* 这里没有代码*/} // 这是一个Finalize方法 ~CriticalFinalizerObject(){/* 这里没有代码*/ }}我知道,这个类看翻译 2020-11-05 19:36:12 · 121 阅读 · 0 评论 -
.net 使用终结操作来释放本地资源
大多数类型只需内存就可以正常工作。但是,也有一些类型除了要使用内存,还要使用本地资源。例如,System.IO.FileStream 类型需要打开一个文件(本地资源)并保存文件的句柄。然后该类型的Read和Write方法用该句柄来操作文件。类似地,System.Threading.Mutex类型要打开一个Windows互斥体内核对象(本地资源)并保存其句柄,并在调用Mutex的方法时使用该句柄。终止(finalization)是CLR提供的一种机制,允许对象在垃圾回收期回收其内存之前执行一些得体的清理工翻译 2020-11-03 22:28:02 · 315 阅读 · 0 评论 -
.net 垃圾回收与调试
using System;using System.Threading;public static class Program{ public static void Main(){ //创建一个Timer对象,每隔2000毫秒就调用一次TimerCallBack方法 Timer t= new Timer(TimerCallBack, null, 0, 2000); Console.ReadLine(); } private static void TimerCallBac原创 2020-11-02 23:07:55 · 97 阅读 · 0 评论 -
.net 基元用户模式和内核模式构造
基元线程同步构造。所谓基元,我的意思是指可以在代码中使用的最简单的构造。由两种基元构造:用户模式(user-mode)和内核模式(kenel-mode).应该尽量使用基元用户模式构造,它们的速度要显著快于内核模式的构造。这是因为它们使用了特殊CPU指令来协调线程。这意味着协调是在硬件中发生的(所以才这么快)。但是,这同时意味着Microsoft Windows操作系统永远检测不到一个线程在一个基元用户模式中构造上的阻塞了。由于在用户模式的基元构造上阻塞的一个线程池线程永远不认为已经阻塞,所以线程池不会创建一原创 2020-10-31 20:38:54 · 238 阅读 · 0 评论 -
.net 类库和线程安全
现在,我们简单地谈一谈类库和线程同步。Microsoft的Framework Class Library(FCL) 保证所有静态方法都是线程安全的。这意味着假如两个线程同时调用一个静态方法,不会由数据被损坏。FLC必须在内部做到这一点,因为开发不同程序集的多个公司不可能事先协商好使用一个锁来仲裁对资源的访问。Console类包含一个静态字段,类的许多方法都要获取和释放这个字段上的锁,以确保一次只有一个线程访问控制台。要郑重声明的是,使一个方法线程安全,并不是说它一定要在内部获取一个线程同步锁。一个线程安全原创 2020-10-31 19:36:50 · 448 阅读 · 0 评论 -
.net线程核心处理机制(1)
一个线程池阻塞(block)时,线程池会创建额外的线程,而创建、销毁和调度线程所需的时间和内存资源时相当昂贵的。另外,许多开发人员在看见自己程序中的线程没有在任何有用的事情时,他们的习惯时创建更多的线程,期望新线程能做有用的事情。为了构建可伸缩的、具有良好响应能力的应用程序,关键在于不要阻塞你拥有的线程,使它们能用于执行其他任务。多个线程同时访问共享资源时,线程同步用于防止数据损坏。我之所以强调“同时”,是因为线程同步问题就是计时问题。如果有一些数据需要由两个线程访问,但那些线程不可能同时接触到数据,就完原创 2020-10-31 18:50:06 · 72 阅读 · 0 评论 -
.net 垃圾回收算法
垃圾回收器检查托管堆中是否有应用程序不再使用的任何对象。如果有,它们使用的内存就可以回收(如果一次垃圾回收之后,堆中仍然没有可用的内存,new操作符将会抛出一个OutOfMemoryException)。垃圾回收期如何知道应用程序正在使用一个对象?你或许已经想到,这不是一个三言两语就能说清楚的问题。每个应用程序都包含一组根(root)。每个根都是一个存储位置,其中包含指向引用类型对象的一个指针。该指针要么引用托管堆中的一个对象,要么为NULL 。例如,类型中定义个任何静态字段都认为是一个根。除此以外,任何原创 2020-10-31 12:27:00 · 81 阅读 · 0 评论 -
.net 从托管堆分配资源
CLR要求所有的资源都从托管堆(managed heap)分配。这个堆和c运行时堆非常相似,只是你永远不从托管堆中删除对象——应用程序不需要的对象会自动删除。这自然引起一个问题:“托管堆如何知道应用程序不再用一个对象?”我稍后就会回答这个问题。目前使用的垃圾回收算法有好几种。每种算法都针对特定环境进行优化,能提供这种环境下最佳的性能。本章关注的是Microsoft .NET Framework 的CLR所采用的垃圾回收算法。先从最基本的概念讲起。进程初始化,CLR要保留一块连续的地址空间,这个地址空间最原创 2020-10-31 10:34:28 · 58 阅读 · 0 评论 -
.net自动内存管理(垃圾回收)
一,理解垃圾回收平台的基本工作原理每个程序都要使用这样或那样的资源,比如文件、内存缓冲区、屏幕空间、网络连接、数据库资源等。事实上,在面向对象的环境中,每个类型都代表可供程序使用的一种资源。要使用这些资源,必须为代表资源的类型分配内存。以下是访问一个资源所需的具体步骤1,调用IL指令newobj, 为代表资源的类型分配内存。在C#中使用new操作符,编译器就会自动生成该指令。2,初始化内存,设置资源的初始状态,使资源可用。类型的实例构造器负责设置该初始状态。3,访问类型的成员来使用资源。4,摧毁资原创 2020-10-29 22:45:42 · 313 阅读 · 0 评论 -
.net异常处理的性能问题
开发人员社区经常就异常处理的性能问题展开活跃争论。有人说异常处理性能很差,以至于他们根本就不打算使用。但是,我认为在面向对象平台中,异常处理不是一个可有可无的东西,而是必须的!另外,假若不用它,有什么是可以替代的呢?让方法返回bool值类型标识成功或失败,还是使用某种错误代码enum类型?如果真的这样做,那么两个世界中最坏的情况都会发生;CLR和类库都会抛出异常而你的代码会返回错误代码。现在你的代码两者都要应对。异常处理和较常规的报告异常的方式相比,很难看出两者的性能差异。如果写代码检查每个方法调用的返回原创 2020-10-28 21:30:36 · 219 阅读 · 0 评论 -
.net 异常和状态管理(2)
关于异常的发生有意见好事在于,未处理异常会造成应用程序终止。之所以说这是一件好事,是因为可以在测试期间快速发现问题。利用由未处理的异常提供的信息(错误信息和堆栈跟踪),通常足以完成对代码的修正。当然,许多开发人员不希望他们的应用程序在测试和部署之后继续发生意外终止的情况,所以他们会插入代码来捕捉System.Exception,也就是所有异常类型的基类。然而,如果捕捉System.Exception并允许应用程序继续运行,一原创 2020-10-26 22:50:39 · 125 阅读 · 0 评论 -
net 异常和状态管理(3)
一,发生异常以后为了确保清理代码的执行是如此重要,以至于许多编程语言都提供了一些构造来简化清理代码的编写。例如只要使用了lock, using 和foreach 语句,C#编译器就会自动生成try/finally块。另外,重写一个类的析构器(Finalize方法)时,C#编译器也会生成try/finally块。使用这些构造时,编译器将你写的代码放到try块内部,并自动将清理代码放到finally块中。具体如下所示。1)使用lock语句时,锁会在finally块中释放。2)使用using语句时,会在fin原创 2020-10-27 21:13:54 · 152 阅读 · 0 评论 -
.net 异常和状态管理(1)
.net核心机制1,定义异常设计类型时,首先要想好类型的各种使用情况。类型名称通常是一个名词,例如FileStream或者StringBuilder。然后,要为类型定义属性、方法、事件等。这些成员(属性的数据类型、方法的参数、返回值等)的定义方式就是类型的编程接口。这些成员代表类或者类型实例可以执行的行动。行动成员通常用动词表示,例如Read,Write,Flush,Append,Insert 和Remove等。当行动成员不能完成任务时,就应抛出异常。定义:异常是指成员没有完成它的名称宣称可以完成的行原创 2020-10-25 11:52:07 · 77 阅读 · 0 评论