前言
在看《CLR》的時候,作者在開篇的時候提到了NGen.exe,前面一節執行程序集的代碼中提到:程序或方法執行前會執行MSCorEE.dll中的JIT函數把要執行方法的IL轉換成本地的CPU指令,講代碼放在內存塊中,第二次調用方法的時候,由于已對方法進行了驗證和編譯,所以會直接執行內存塊中的代碼,不需要再執行JIT函數編譯了。因為在方法沒調用之前都會要調用JIT函數編譯,在這一節的最后作者也提到,通過實驗表明,CLR的JIT編譯器似乎沒有使自己的應用程序達到應有的性能,然后就提到了.Net Framework SDK提供的NGen.exe工具。
疑問
當時看到這段話的時候很興奮,然后就接著看作者寫的NGen.exe的介紹,可惜作者只用了幾頁的篇幅講了下,感覺太少了,也有些疑問,然后就在MSDN上搜,找到了《Ngen.exe(本機映像生成器)》,仔細看了下,和作者寫的差不多,其中詳細寫了NGen.exe的用法,自己也照著上面的方法,自己敲了個遍,可能是官方寫的太官方或是小弟理解能力有限,總有點云里霧里的,然后又在博客園找到了一位園友寫的《本機影像生成器(Ngen.exe)工具使用實踐》,仔細看了下,主要是NGen.exe項目的簡單應用,不是很全面的介紹NGen.exe的用法。
結合上面所接觸的,有幾個疑問:
1,JIT編譯器的執行條件
上面那位博文的作者在文章中提到
但是《CLR》這本書的作者在寫執行程序集中的代碼這一節中提到:JIT編譯器將本地CPU指令存儲到動態內存中。一旦應用程序終止,編譯好的代碼也會被丟棄。所以再次運行應用程序,JIT編譯器必須再次將IL代碼編譯成本地指令。
就是說程序終止,再次運行程序還是會執行JIT編譯器的。但是與上面“實時編譯只在程序第一次運行時編譯”有點矛盾。
2,NGen.exe的作用
MSDN和《CLR》的作者都說了NGen.exe的作用有兩點,改善內存使用情況和更快的應用程序啟動速度,這里我只說使應用程序啟動速度加快。
NGen.exe操作會把相應的程序集的IL代碼編譯成本地代碼,放到磁盤的某一目錄下,下次執行程序的時候CLR會檢測是否存在對應程序集由NGen.exe生成的文件,若不存在執行JIT編譯器編譯,若存在跳過JIT編譯器,JIT編譯器執行的條件是在執行方法之前編譯,這時候我就有點迷糊了,MSDN上寫的是NGen.exe的作用是使應用程序啟動的速度加快而不是程序運行的速度加快,就是說在程序運行的時候,如果調用某一方法,還是會執行JIT編譯器的,就有點矛盾了。或者這樣說JIT編譯器是不是在程序啟動的時候執行,執行所有代碼的編譯?如果是,那NGen.exe使程序啟動的速度加快這個作用是對的,我個人感覺并不是這樣,比較那么納悶的是為什么沒有使程序運行的速度加快,因為NGen.exe已經把相關的程序集編譯好了,程序調用某一方法的時候就不需要再執行JIT編譯器了,少了編譯速度不是更快了?
3,NGen.exe安裝程序集依賴項
MSDN中提到
但是我試了下并沒有安裝程序的依賴項
4,NGen.exe檢測映像變化
或者不是NGen.exe檢測,其他的方式暫時也沒發現,如果是自己程序中的程序集發生變化可以通過程序來判斷,但是外部的變化就不太好檢測了,比如:
5,NGen.exe更新映像
MSDN提供了兩種更新映像的方式,但是沒有指定程序集更新,如果說程序集發生變化,就需要全部更新映像花費時間太長,下面的更新方式的說明不是很清楚,不知是不是自動檢測映像變化更新。
后記
以上疑問,跪求大神指點。。。。
不知是用NGen.exe后會性能會優化多少,暫時沒有找到相關的方法測試,有機會會好好測試下,想想NGen.exe的用武之地應該是大型的Winfrom項目,而且業務邏輯應該很復雜的那種,如果只是簡單的程序,就沒這個必要了。
文章列表