国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

重讀 CLR via C# 筆記

2019-11-17 03:14:11
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

重讀 CLR via C# 筆記

《CLR via C#》第四版

JIT性能

  為什么有時(shí)候有JIT的語(yǔ)言會(huì)比直接編譯為機(jī)器碼的語(yǔ)言快?

  簡(jiǎn)而言之,就是JIT所知道的信息比那些在開發(fā)機(jī)上直接編譯為機(jī)器碼的的編譯器知道的信息更多,有的時(shí)候這些信息是如此的有用,以至于效果可以超過(guò)JIT本身的開銷和JIT編譯時(shí)間受限帶來(lái)的限制。《CLR》給出了如下三種具體的原因:

  1、 JIT知道當(dāng)前正在使用的CPU的特性,可以使用那些在當(dāng)前CPU上具備的新指令集。而傳統(tǒng)編譯器只能按照開發(fā)人員的指示,限制為僅使用較通用的指令集。更重要的是,這個(gè)過(guò)程是自動(dòng)的,對(duì)開發(fā)人員透明的。

  2、 在執(zhí)行環(huán)境中,程序中有些變量可能已經(jīng)變?yōu)槌A浚绠?dāng)前CPU核心數(shù)、當(dāng)前進(jìn)程是否為64位進(jìn)程、進(jìn)程啟動(dòng)時(shí)的命令行參數(shù),這樣程序中依賴這些變量的分支/邏輯就可以被優(yōu)化。給JIT進(jìn)一步優(yōu)化最終代碼提供了操作空間。

  3、 JIT并未只生成代碼一次,在程序運(yùn)行過(guò)程中,還可以監(jiān)視那些部分是程序的熱點(diǎn),即被大量反復(fù)執(zhí)行的代碼,對(duì)這些代碼可以根據(jù)PRofile的信息重新生成更為優(yōu)化的代碼。

  除此以外,我認(rèn)為還有一個(gè)重要的原因是:

    JIT可以跨越程序集文件的邊界來(lái)進(jìn)行優(yōu)化、內(nèi)聯(lián),這些程序集在編譯生成的時(shí)候可能是在不同的時(shí)間、不同的機(jī)器上,傳統(tǒng)編譯器對(duì)此無(wú)能為力。

checked 關(guān)鍵字

  checked 關(guān)鍵字的作用范圍僅在當(dāng)前所在函數(shù)內(nèi),不影響checked塊中調(diào)用的函數(shù),所以下面這段代碼不會(huì)拋異常

class Program{    static void Main(string[] args)    {        checked        {            Test();        }    }    private static void Test()    {        byte a = 100;        a += 200;    }}

  其實(shí)想想也正常,checked關(guān)鍵字的作用是將數(shù)值運(yùn)算編譯為帶檢查的IL指令,如果調(diào)用的函數(shù)在另一個(gè)程序集中,該程序集早已被編譯好,又如何改變呢?

  但注意:Decimal并非基本類型,四則運(yùn)算沒有IL指令對(duì)應(yīng),所以不受checked影響,其運(yùn)算始終會(huì)拋異常。

值類型和引用類型

  值類型表示不會(huì)額外為此對(duì)象在對(duì)上分配,而值類型自己可能被包含在一個(gè)引用類型中,所以值類型未必不會(huì)在堆上。

  值類型也用new關(guān)鍵字,容易給人造成誤解。

  值類型可以通過(guò)顯示指定將多個(gè)值類型的字段重疊在一起。

  只有C++/CLI才能獲得指向已裝箱的值類型的指針,C#只能先拆箱。

  當(dāng)作為模板的類型參數(shù)時(shí),值類型會(huì)強(qiáng)制CLR為它專門生成一份特化的代碼,而只有引用類型的模板實(shí)例可以共享代碼,減少內(nèi)存占用。

個(gè)人經(jīng)驗(yàn):

  引用類型new一次只有一個(gè)實(shí)例,而值類型則未必,當(dāng)值類型被傳遞和修改,其行為需要仔細(xì)分析各個(gè)值類型變量的生存期,給開發(fā)人員帶來(lái)不小的負(fù)擔(dān),這里面包括所謂的裝箱拆箱。建議只在局部范圍內(nèi)或是作為只讀對(duì)象的情況下才考慮使用,因?yàn)镃#碼農(nóng)普遍沒有C++碼農(nóng)那樣對(duì)對(duì)象生存期有明確的把握的能力,容易被豬隊(duì)友害死。

GC相關(guān)

  在GC回收時(shí),某個(gè)對(duì)象即使沒超出C++意義上的生存范圍(所在的塊),但由于在下面未運(yùn)行的代碼中沒有被引用所以一樣會(huì)被認(rèn)為沒有被引用而被GC。在/debug模式下,對(duì)象生存期會(huì)延長(zhǎng)到函數(shù)體結(jié)束。

using System; using System.Threading; public static class Program {     public static void Main() {         // Create a Timer object that knows to call our TimerCallback         // method once every 2000 milliseconds.         Timer t = new Timer(TimerCallback, null, 0, 2000);        // Wait for the user to hit <Enter>.         Console.ReadLine();     }     private static void TimerCallback(Object o) {         // Display the date/time when this method got called.         Console.WriteLine("In TimerCallback: " + DateTime.Now);  //Only once!        // Force a garbage collection to occur for this demo.         GC.Collect();     } }

  在進(jìn)程正常結(jié)束的時(shí)候CLR也會(huì)執(zhí)行GC過(guò)程,并釋放對(duì)象。

CriticalFinalizerObject

  對(duì)于非托管的資源,建議使用SafeHandle系列管理其句柄,其基類CriticalFinalizerObject有如下CLR級(jí)別支持的額外特性:

1、 從CriticalFinalizerObject繼承的類型首次被引用時(shí),會(huì)JIT其析構(gòu)函數(shù),確保其在析構(gòu)時(shí)不會(huì)因內(nèi)存不足而失敗。

2、 在析構(gòu)時(shí),會(huì)優(yōu)先析構(gòu)其他不是從CriticalFinalizerObject繼承的對(duì)象,使得在普通類型的析構(gòu)函數(shù)中可以使用CriticalFinalizerObject類型的對(duì)象。

3、 當(dāng)整個(gè)AppDomain被強(qiáng)行卸載時(shí),CriticalFinalizerObject對(duì)象的析構(gòu)函數(shù)仍然會(huì)被調(diào)用。

  此外:

1、 SafeHandle對(duì)象可以在P/Invoke時(shí)替代IntPtr作為參數(shù)和返回類型,確保異常安全。

2、 P/Invoke時(shí)會(huì)正確管理內(nèi)部的引用計(jì)數(shù),確保多線程引用的情況下不會(huì)被提前意外釋放。

3、 CriticalHandle是不帶引用計(jì)數(shù)的SafeHandle。

4、 SafeHandle和CriticalHandle及其子類都是抽象類,在具體場(chǎng)景需要通過(guò)繼承的方式使用。

雜類

  dynamic類型被處理為Object+DynamicAttribute,所以不能通過(guò)Object和dynamic來(lái)實(shí)現(xiàn)不同的重載。

  const的值會(huì)在編譯時(shí)被內(nèi)聯(lián),readonly則不會(huì),所以未來(lái)可能需要改動(dòng)的值不應(yīng)該用const。

  Nullable類型在裝箱時(shí)CLR會(huì)特殊處理,脫掉Nullable,即null被裝箱為null,v被裝箱為v,而不是Nullable<V>類型。

  可以通過(guò)AppDomain的FirstChanceException事件監(jiān)視異常被拋出,但事件回調(diào)函數(shù)不能處理這個(gè)異常。

  如果一個(gè)異常沒有被CLR處理,被報(bào)告至Windows Error Reporting,那么它獲得的調(diào)用棧只能到最近一次被throw或是re-throw的位置,即re-throw對(duì)Windows Error Reporting無(wú)效,仍然會(huì)重置異常拋出點(diǎn)。

  在Catch和Finally塊中,線程不會(huì)被Abort所中斷.

  Environment.FailFast可以跳過(guò)普通的異常處理邏輯和對(duì)象Finalize方法直接結(jié)束進(jìn)程。

  使用反射調(diào)用時(shí),如果拋出異常,會(huì)將該異常包裹為TargetInvocationException;dynamic不受此影響。

  Constrained Execution Regions (CERs),該功能可以讓CLR預(yù)先在try塊之前“準(zhǔn)備”一段代碼,而不是在運(yùn)行過(guò)程中由于載入DLL失敗、類靜態(tài)初始化失敗等原因拋出異常。

  Thread.Sleep(0)可以將CPU讓給同優(yōu)先級(jí)或更高優(yōu)先級(jí)的線程,而Thread.Yield可以將CPU讓給更低優(yōu)先級(jí)的,介于Thread.Sleep(0)和Thread.Sleep(1)之間。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 西贡区| 和顺县| 恩平市| 芮城县| 桓仁| 安龙县| 平远县| 镇坪县| 仁布县| 满城县| 宁武县| 三原县| 佛山市| 沛县| 文安县| 开远市| 尉氏县| 英吉沙县| 迭部县| 封开县| 泸定县| 巴中市| 同江市| 常州市| 城市| 尚志市| 利津县| 肥城市| 扶绥县| 武定县| 六安市| 永丰县| 北安市| 崇州市| 商河县| 陕西省| 邯郸市| 安远县| 潍坊市| 寿光市| 宁波市|