接觸NET也有1年左右的時間了,NET的內部實現對我產生了很大的吸引力。個人覺得:能對這些底部的實現進行了解和熟練的話,對以后自己寫代碼是有很大幫助的,好了,廢話不多說,請看下邊:
.NET CLR 和 Java VM 都是堆疊式虛擬機器(Stack-Based VM),也就是說,它們的指令集(Instruction Set)都是採用堆疊運算的方式:執行時的資料都是先放在堆疊中,再進行運算。JavaVM 有約 200 個指令(Instruction),每個指令都是 1 byte 的 opcode(操作碼),后面接不等數目的參數;.NET CLR 有超過 220個指令,但是有些指令使用相同的 opcode,所以 opcode 的數目比指令數略少。特別注意,.NET 的 opcode 長度並不固定,大部分的 opcode 長度是 1 byte,少部分是 2 byte。
下面是一個簡單的 C# 原始碼:
代碼如下:
using System;
public class Test {
public static void Main(String[] args) {
int i=1;
int j=2;
int k=3;
int answer = i+j+k;
Console.WriteLine("i+j+k="+answer);
}
}
將此原始碼編譯之后,可以得到一個 EXE的程序。我們可以通過 ILDASM.EXE(圖-0) 來反編譯 EXE 以觀察IL。我將 Main() 的 IL 反編譯條列如下,這裡共有十八道IL 指令,有的指令(例如 ldstr 與 box)后面需要接參數,有的指令(例如 ldc.i4.1 與與add)后面不需要接參數。

此程式執行時,關鍵的記憶體有三種,分別是:
1、Managed Heap:這是動態配置(Dynamic Allocation)的記憶體,由 Garbage Collector(GC)在執行時自動管理,整個Process 共用一個 Managed Heap。
2、Call Stack:這是由 .NET CLR 在執行時自動管理的記憶體,每個 Thread 都有自己專屬的 Call Stack。每呼叫一次 method,就會使得Call Stack 上多了一個 Record Frame;呼叫完畢之后,此 Record Frame 會被丟棄。一般來說,Record Frame 內記錄著 method 參數(Parameter)、返回位址(Return Address)、以及區域變數(Local Variable)。Java VM 和 .NET CLR 都是使用 0, 1, 2… 編號的方式來識別區別變數。
新聞熱點
疑難解答
圖片精選