• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • <展現C#> 第二章 NGWS Runtime 技術基礎(rainbow 翻譯)

    發表于:2007-06-30來源:作者:點擊數: 標簽:
    第二章 NGWS runtime 技術基礎 既然你已經具有了C#全面的印象,我也想讓你了解NGWS runtime的全貌。C#依靠由NGWS提供的運行時;因此,有必要 知道運行時如何工作,以及它背后所蘊含的概念。 所以,這一章分為兩部分——它們是所有的概念和使用的基
    第二章 NGWS runtime 技術基礎

    既然你已經具有了C#全面的印象,我也想讓你了解NGWS runtime的全貌。C#依靠由NGWS提供的運行時;因此,有必要
    知道運行時如何工作,以及它背后所蘊含的概念。
    所以,這一章分為兩部分——它們是所有的概念和使用的基礎。兩部分的內容雖然有些重疊,但它有助于加深理解正
    在學習的概念。

    2.1 NGWS Runtime
    NGWS和NGWS Runtime為你提供了一種運行時環境。該運行時管理執行代碼,并提供了使編程更容易的服務。只要你的
    編譯器支持這種運行時,你就會從這種受管理的執行環境中得益。
    你猜測C#編譯器支持NGWS runtime很正確,但是不僅它支持NGWS runtime,VB和C++也支持。這些為支持運行時所創建
    的代碼稱作"受管代碼"(managed code)。以下是你的應用程序從NGWS runtime那里所得到的利益:

    交叉語言集成(通過通用語言規范)
    自動內存管理(垃圾收集)
    交叉語言異常處理(統一展開)
    增強安全(包括類型安全)
    版本支持("DLL地獄"終結者)
    組件交互簡化模式

    因NGWS runtime 要提供了所有的這些好處,編譯器必須把元文件和受管代碼一起發出。元文件描述代碼中的類型,它
    和你的代碼存在一起(與PE類似---PE為可變位執行文件)
    正如你從很多種交叉語言功能所看到的,NGWS runtime主要是關于高度集成交叉多異編程語言(tight integration
    across multiple different programming languages)。這種支持可達到允許你從一個VB對象派生出一個C#類的程度(我后
    面會給出要討論的文章)。
    C#程序員將會喜歡的一個功能是,他們不必擔心內存管理—也就是說不必擔心臭名昭著的內存泄漏。NGWS runtime提
    供了內存管理,當對象和變量的生命期結束(不再被引用)時,垃圾收集器釋放它們。我真的喜歡這個功能,因為在COM中的
    內存管理一直是我的一塊心病。
    應該鼓勵配置一個管理應用程序或者組件。因為管理應用程序含有元數據文件,NGWS runtime可以利用這些信息,以
    確保你的應用程序具有它所需的各種規定版本。所產生的明顯效果為,由于你的代碼沒有相互之間的依賴,很少可能出現
    中斷。
    這章余下來的將分為兩部分,每一部分討論NGWS runtime的各個方面,直到你的C#應用程序能執行為止。
    1、中間語言(Intermediate Language,縮寫IL)和元數據
    2、即時編譯器(just-in-time compliers,簡稱JITers)

    2.1.1 中間語言和元數據
    由C#編譯器生成的受管代碼并不是原始代碼,但它是中間語言(IL)代碼。這種IL代碼自身變成了NGWS runtime的受管
    執行進程的入口。IL代碼明顯的優勢在于它是CPU無關的,這也意味著,你要用目標機器上的一個編譯器才能把IL代碼轉換
    成原始代碼。
    盡管IL代碼由編譯器產生,但它并不是編譯器提供給運行時僅有的東西。編譯器同樣產生有關你代碼的元數據,它告
    訴運行時有關你代碼的更多的東西,例如各種類型的定義、各種類型成員的簽名以及其它數據?;旧?,元數據是類型
    庫、注冊表內容和其它用于COM的信息。盡管如此,元數據還是直接和執行代碼合并在一起,并不處在隔離的位置。
    IL和元數據存放于擴展了PE格式的文件中(PE格式用于.exe和.dll文件)。當這樣的一個PE文件被裝載時,運行時從文
    件中定位和分離出元數據和IL。
    在進一步說明之前,我想給你已有的IL指令的簡短目錄。盡管它不是一個完整的清單,也不需要你熟記和理解,但是
    它列出了你所必需的、C#程序所基于的知識基礎。

    算術和邏輯操作符
    控制流
    直接內存訪問
    堆棧操作
    參數和局部變量
    堆棧分配
    對象模式
    實例類型值
    臨界區
    數組
    分型位置
    即時編譯器(JITters)

    2.1.2 即時編譯器(JITters)
    由C#或其它能產生受管代碼的編譯器所生成的受管代碼就是IL碼。雖然IL代碼被包裝在一個有效的PE文件中,但是你
    還是不能執行它,除非它被轉換成為受管原始代碼。這就是NGWS runtime 即時編譯器(也稱作JITters)大顯身手的時候。
    為什么你會對即時編譯代碼感到厭繁, 為什么不把整個IL PE文件編譯成原始代碼? 答案是時間——需要把IL代碼編
    譯成CPU規格的代碼的時間。這種編譯將更加有效率,因為一些程序段從來就沒有被執行過。例如,在我的字處理器中,郵
    件合并功能從來就沒有被編譯。
    從技術上說,全部的處理過程如下:當一個類型被裝載時,裝載器創建一個存根(stub),并使它連接每一個類型的方
    法。當一個方法第一次被調用時,存根把控制交給JIT。JIT把IL編譯為原始代碼,且把存根指針指向緩沖了的原始代碼。
    接著的調用將執行原始碼。在某些位置上(At some point),所有的IL都被轉換成為原始代碼,而JITter處于空閑狀態。
    正如我在前面提到的,JIT編譯器有很多,不止一個。在Windows平臺上,NGWS runtime裝有3個不同的JIT編譯器。
    JIT——這是NGWS runtime默認使用的JIT編譯器。它是一個后臺(back end)優化的編譯器 ,在前臺(up front)實行數
    據流分析,并創建了高度優化的受管原始代碼做為輸出結果。JIT可以使用不嚴格的IL指令集編碼,但是所需資源將十分可
    觀。主要的限制在于內存足跡(footprint)、結果工作集,以及實行優化所消耗的時間。
    EconoJIT—— 和主JIT相比,EconJIT的目標是把IL高速地轉換成受管原始代碼。它允許緩沖所產生的原始代碼,但是
    輸出碼并不象主JIT生成的代碼那樣優化(代碼小)。當內存緊張時,快速代碼生成方案的優勢將蕩然無存。通過永久地拋棄
    無用的已JIT過的代碼,你可以把更大的IL程序裝入代碼緩沖區。因為JIT編譯快,執行速度也仍然很快。
    PreJIT—盡管它是基于主JIT的,但操作起來更象是一個傳 統的編譯器。你安裝了NGWS組件,它才能運行,才可以把
    IL代碼編譯成受管原始代碼。當然最終的結果為,更快的裝載時間和更快的應用程序啟動時間(不需要更多的JIT編譯)。
    在所列出的JITters中,有兩個是運行時的JITters??墒悄阍趺礇Q定要使用哪一個JIT,它如何使用內存? 有一個稱
    做"JIT編譯管理器"的小應用程序(jitman.exe),它存放于NGWS SDK安裝目錄下的bin目錄中。當執行該程序時,它把一個
    圖標加到系統任務條上,雙擊該圖標打開程序對話框(見圖2.1)。

    圖2.1 JIT編譯管理器允許你設置各種相關性能的選項

    盡管它是一個小小的對話框,可是你所選擇的選項功能是相當強大的。每一個選項將在以下描述。
    Use EconoJIT only 選項——當該復選框沒有選上時,NGWS runtime使用默認的正常的JIT編譯器。前面就曾經解釋過
    兩種JITter的區別。
    Max Code Pitch Overhead(%)選項——該設置僅保留給EconoJIT。它控制了JIT編譯時間和執行代碼時間的百分比。如
    果超過了設定的域值,代碼緩沖區得到擴充,以縮短JIT編譯所消耗的時間。
    Limit Size of Code Cache選項——該項默認為非選。沒有選擇該項意味著緩沖區將使用它所能得到的內存。如果你
    想限制緩沖區大小,復選該選項,這將允許你使用Max Size of Cache(bytes)選項。
    Max Size of Cache(bytes)選項—控制容納JIT代碼的緩沖區的最大值。雖然你可以非常嚴格地限制這個值,但你
    還是應該小心,不能超過這個緩沖區所適合的最大值。否則該方法的JIT編譯將會失敗。
    Optimize For Size選項——告訴JIT 編譯器,優化的目的是為了使代碼更小而不是能執行得更快。這個設置默認是關
    掉的。
    Enable Concurrent GC[garbage collection]選 項——垃圾收集(GC)默認地運行在用戶代碼的線程中。意味GC發生
    時,可能會注意到回應有輕微的延遲。為防止出現該現象,打開當前GC。注意,當前GC比標準GC更慢,它僅在windows
    2000上寫時(the time of writing)有效。
    當用C#創建項目時,你可能使用不同的設置試驗過。當創建 UI-intensive應用程序時,你將會看到允許當前GC的最大
    差別。

    2.2 虛擬對象系統(VOS)
    到目前為止,你僅看到了NGWS runtime如何工作,但是并不了解它工作的技術背景以及為什么它要這樣工作。這節都
    是關于 NGWS 虛擬對象系統的(VOS)。
    以下為在VOS中形成聲明、使用和管理類型模型時,NGWS runtime的規則。在VOS背后的思想是建立一個框架,在執行
    代碼時不能犧牲性能,允許交叉語言集成和類型安全。
    我提到的框架是運行時架構的基礎。為了幫助你更好地了解它,我將它勾出四個區域。當開發C#應用程序和組件時,
    理解它們很重要。
    VOS類型系統——提供豐富的類型系統,它打算支持全面編程語言的完全實施。
    元數據——描述和引用VOS類型系統所定義的類型。元數據的永久格式與編程語言無關,但是,元數據拿自己當作一種
    互換機制(nterchange mechanism)來使用,這種互換是在在工具和NGWS的虛擬執行系統之間。
    通用語言規范(CLS)——CLS定義了VOS中類型的子集,也定義了常規的用法。如果一個類庫遵守CLS的規則,它確保類
    庫可以在其它所有能實現CLS的編程語言上使用。
    虛擬執行系統(VES)——這是VOS實時的實現。VES負責裝入和執行為NGWS運得時編寫的程序。
    這四個部分一起組成了NGWS runtime架構。每一部分在下面小節中描述。

    2.2.1 VOS類型系統
    VOS類型系統提供豐富的類型系統,它打算支持多種編程語言的完全實施。所以,VOS必須都支持面向對象的語言和過
    程編程語言。
    現在,存在著很多種近似但有點不兼容的類型。就拿整型當例子,在VB中,它是16位長,而在C++中,它是32位。還有
    更多的例子,特別是用在日期和時間以及數據庫方面的數據類型。這種不兼容使應用程序的創建和維護不必要地復雜化,
    尤其當程序使用了多種編程語言時。
    另一個問題是,因為編程語言之間存在著一些差別,你不能在一種語言中重用另一種語言創建的類型。(COM用二進制
    標準接口部分地解決了這個問題)。 當今代碼重用肯定是有限的。
    發布應用程序的最大障礙是各種編程語言的對象模型不統一。幾乎每一方面都存在著差異:事件、屬性、永久保存
    (persistence)等等。
    VOS這里將改變 這種現象 。VOS定義了描述值的類型,并規定了類型的所有值所必須支持的一條合約。由于前面提到
    的支持面向對象和過程編程語言,就存在著兩種值和對象。

    對于值,類型存儲于表述(representation)中,同樣操作也在其中實行。對象更強大因為它顯式地存于表述中。每一
    個對象都有一個區別于其它對象的識別號。支持不同的VOS類型在第四章 "C#類型"中提出。


    2.2.2元數據
    盡管元數據用于描述和引用由VOS類型系統定義的類型,但它還不能鎖定到這個單個目標。當你寫一個程序時,通過利
    用類型聲明,你所聲明的類型(假定它們是數值類型或引用類型)被介紹給NGWS runtime類型系統。類型聲明在存于PE可執
    行文件內部的元數據中得到描述。
    基本上,元數據用于各項任務:用于表示NGWS runtime用途的信息,如定位和裝載類、 內存中這些類的事例、解決
    調用 、翻譯IL為原始碼、加強安全并設置運行時上下文邊界。
    你不必關心元數據的生成。元數據是由C#的"代碼轉IL編譯器"(code-to-IL compiler,不是JIT編譯器)生成的。代碼轉
    IL編譯器發送二進制元數據信息給PE文件,是以標準的方式發送的,不象C++編譯器那樣,為出口函數創建它們自己的修飾
    名字。
    你從元數據和可執行代碼并存所獲得的主要優勢為,有關類型的信息同類型自身固定在一起,不會遍布很多地方。同
    樣有助于解決存在于COM中的版本問題。進一步地,你可以在相同的上下文中使用不同的版本庫,因為庫不僅被注冊表引
    用,也被包含在可執行代碼中的元數據引用。


    2.2.3通用語言規范
    通用語言規范(CLS)并不是虛擬對象系統(VOS)真正的一部分,它是特殊的。CLS定義了VOS中的一個類型子集,也定義
    了必須符合CLS的常規用法。
    那么,對此有什么迷惑呢?如果一個類庫遵守CLS規則,其它編程語言同樣也遵守CLS規則,那么其它編程語言的客戶也
    可以使用類庫。CLS是關于語言的交互可操作性(interoperability)。因此,常規用法必須僅遵循外部可訪問項目
    (externally visible items)如方法、屬性和事件等等。
    我所描述的優點是你可以做以下工作。用C#寫一個組件,在VB中派生它,因加在VB中的功能是如此之強大,在C#中再
    次從VB類派生它。只要所有的外部可訪問項遵守CLS規則,這樣是可行的。
    我在這本書中出示的代碼不關心CLS協定。但在構建你的類庫時要注意到CLS協定。我提供了表2.1,用以給類型和外部
    可訪問項定義協定規則。
    這個清單不完整。它僅包含一些很重要的項目。我不指出出現在本書中每一種類型的CLS協定,所以有個好主意:當你
    尋找CLS協定時,至少應該用瀏覽該表,以了解哪種功能有效。不要擔心你不熟悉這章表中的每一個含義,在這本書中你會
    學到它們。

    表2.1 通能語言規范中的類型和功能

    bool
    char
    byte
    short
    int
    long
    float
    double
    string
    object(所有對象之母)

    Arrays(數組)
    數組的維數必須是已知的(>=1),而且最小下標數必須為0。
    要素類型必須是一個CLS類型。

    類型(Types)
    可以被抽象或隱藏。
    零或更多的接口可以被實現。不同的接口允許擁有具有相同名字和簽名的方法。
    一個類型可以準確地從一個類型派生。允許成員被覆蓋和被隱藏。
    可以有零或更多的成員,它們是字段(fields)、方法、事件或者類型。
    類型可以擁有零或更多個構造函數。
    一種類型的可訪問性可以是公共的或者對NGWS組件來說是局部的;但是,僅公共成員可以認為是類型接口的一部分。
    所有的值型必須從系統值型繼承。異常是一個枚舉——它必須從系統枚舉(System Enum)繼承。

    類型成員
    類型成員允許隱藏或者覆蓋另一種類型中的其它成員。
    參數和返回值的類型都必須是 CLS 協定 類型。
    構造函數、方法和屬性可以被重載。
    一個類型可以有抽象成員,但僅當類型不被封裝時。

    方法
    一種方法可以是靜態、虛擬或者實例。
    虛擬和實例方法可以是抽象的,或者是一個實現。靜態方法必須總擁有一個實現。
    虛擬方法可能是最后的(或者不是)。

    字段(Fields)
    可以是靜態或者是非靜態。
    靜態字段可以被描述或只初始化。

    屬性
    當獲取和設置方法而不是使用屬性語法時,屬性可以公開。
    獲取的返回類型和設置方法的第一個參數必須是相同的CLS類型——屬性的類型。
    屬性名字必須不同,不同的屬性類型用于區分是不充分的。
    由于使用方法實現屬性訪問,如果 PropertyName 是同一個類中定義的一個屬性,你不能實現命名為
    get_PropertyName 和 set_PropertyName 的方法。
    屬性可以被索引。
    屬性訪問必須遵循這種命名格式:get_ProName,set_PropName。

    枚舉(Enumerations)
    強調類型必須是byte、short、int 或long。
    每一個成員是一個枚舉類型的靜態描述字段。
    一個枚舉不能實現任何接口。
    你允許給多字段設定相同的值。
    一個枚舉必須繼承系統枚舉(隱含在C#中)

    異常
    可以被引發和被捕獲。
    自定義異常必須繼承系統異常。

    接口
    可需要實現其它接口。
    一個接口可以定義屬性、事件和虛擬方法。實現取決于派生類。

    事件
    增加和取消方法必須是都提供或者都沒有 ,每一種方法采用一個參數,它是一個從系統代表元(System Delegate)派
    生下來的類。

    自定義屬性
    可以僅使用下更類型:Type(類型),char, char, bool, byte, short, int, long, float, double, enum (一種CLS
    類型), and object.

    代表元(Delegates)
    可以被創建和被激活

    標識符(Identifiers)
    一個標識符的第一個字母必須來自一限制集。
    通過大小寫在單一范圍內,不可能唯一地區別兩個或更多個標識符(大小寫不敏感)。

    2.2.4虛擬執行系統(VES)
    虛擬執行系統實現了虛擬對象系統。通過實現一個負責NGWS runtime的執行引擎(execution engine,縮寫EE)創建
    VES。這個執行引擎執行你用C#編寫和編譯的應用程序。
    下列組件為VES的一部分。
    1、中間語言(IL)——被設計為很容易受各種各樣的編譯器所兼容 。在該框架之外,C++、VB和C#編譯器都能夠生成
    IL。
    2、裝入受管代碼——這包括解決內存中的名字、 表層類(laying out classes ),并且創建JIT編譯所必需的存根。
    通過執行經常性校驗,包括加強一些訪問規則,類裝載器同樣也增強了安全性。
    3、用JIT轉換IL成原始代碼——IL代碼并不是設計成為一種傳統的解釋字節代碼或樹型代碼,IL轉換是真正的編譯。
    4、裝入元數據、校驗類型安全和方法的完整性
    5、垃圾收集(GC)和異常處理——兩者都是基于堆棧格式的服務。受管代碼允許你動態地跟蹤堆棧。要動態地識別各
    個堆??蚣?,JITter或其它編譯器必須提供一個代碼管理器。
    6、描繪和查錯服務——兩者都取決于由源語言編譯器所生成的信息。必須發出兩個映射:一個映射從源語言結構發
    到指令流中的地址,一個映射從地址發到堆??蚣苤械奈恢?。當執行從IL到原始代碼的轉換時,這些映射被重新計算。
    7、管理線程和上下文,還有遠程管理——VES為受管代碼提供這些服務。
    雖然這個清單并不完整,但它足以讓你理解運行時基于的由VES提供的低層架構??隙▽袑iT討論運行時的書,
    而這本書將稍為深入地挖掘各種話題。

    2.3 小結
    這一章,我帶你逛了一回運行時的世界。我描述了當創建、編譯和配置C#程序時它是如何工作的。你學會了中間語言
    (IL),還有元數據是如何用于描述被編譯為IL的類型。元數據和IL都用于JITter檢測和執行你的代碼。你甚至可以選擇用
    哪一種JITter來執行應用程序。
    在這一章的第二部分,涉及到了運行時為何按這種方式工作的理論。你學了虛擬對象系統(VOS)和組成它的那部分。
    對于類庫設計者最為感興趣的就是通用語言規范(CLS),它為基于VOS的語言交互操作設定規則。最后,你看到了虛擬執行
    系統(VES)如何通過NGWS runtime實現VOS。

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>