公共語言運行時&字節碼本地代碼轉化思考

一直以來不同平臺的可執行文件的兼容性一直是計算機發展的困局。爲了使軟件能夠在不同平臺上運行,很多公司或個人都爲此做出了巨大努力。而且有一些語言也是專門針對跨平臺設計的,像java一樣,說實話,就跨平臺的能力來看,java是一款非常不錯跨平臺的語言。然而,事實擺在面前,java編寫的應用軟件無法脫離java虛擬機(也就是java運行時),而且在運行的過程中往往效率低下。對此,我們是不是應該提出一種新的解決方案解決跨平臺與效率的衝突?
首先,我們來探索一下計算機的運行機制。
事實上,所以的,我們編寫出來的程序源碼都是無法直接在電腦上運行。這需要把這些代碼變成目標代碼,這個過程叫編譯,你也可以說這是翻譯,事實上確實如此。然而,目標代碼也不一定就是可執行的。這些代碼也都有別稱如java稱爲字節碼,也就是我們見到的.class文件。當然,這些文件並不能獨立運行,人們提供了另一種方法來運行它,使用C或者是C++編寫的本地可執行程序運行它,很簡單,一個對於class文件,而且你的操作系統又是windows(2000以上)的,而且,你已經設置好了環境變量,就可以使用CMD運行class文件,也可以把命令寫在文本文件中,修改文件後綴名,得到.cmd命令腳本或者.bat的批處理文件雙擊就可以運行class文件,以及jar(源包)
但最終說來,這都是通過運行時實現的,即class文件被java.exe加載到java虛擬機運行的。
你可以想象,一個本可以自己運行的程序卻不能稱作爲程序需要別的代勞,就像一個沒有發動機的大貨車要另一臺火車拖着跑,你能看到速度嗎?如果這個火車又發動機有不一樣了。
下面我們對這種運行時的做法進行一下分析:
還是著名的java運行機制。
對此我們先了解java虛擬機JVM:
JVM是Java Virtual Machine(Java虛擬機)的縮寫,JVM是一種用於計算設備的規範,它是一個虛構出來的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現的。Java虛擬機包括一套字節碼指令集、一組寄存器、一個棧、一個垃圾回收堆和一個存儲方法域。 JVM屏蔽了與具體操作系統平臺相關的信息,使Java程序只需生成在Java虛擬機上運行的目標代碼(字節碼),就可以在多種平臺上不加修改地運行。JVM在執行字節碼時,實際上最終還是把字節碼解釋成具體平臺上的機器指令執行。編譯虛擬機的指令集與編譯微處理器的指令集非常類似。
很顯然,開發基於java語言的應用的跨平臺的移植能力是非常強悍的。jave虛擬機JVM將平臺的特徵隱藏,虛擬出“完全一樣”的java計算機。這樣開發出的應用都是應用在虛擬的java計算機上,又有什麼不可兼容呢?
然而,但我們沉迷在java的與平臺無關性能時,我們的機器或許會感到“疲勞”,
一個小的測試:自己編寫一個只有一個操作的程序,這個操作是輸出“HelloWorld!”分別用C++和java實現。對於C++編譯後生成的本機程序.exe,單獨執行內存256KB,加載到CMD中執行內存爲619KB,而java編譯後的class文件需要java.exe加載執行。內存爲888KB。由於class文件無法自己執行,所以在執行效率方面是完全無法和C/C++這樣的系統編程語言相比。另外,這個C++程序是有GCC編譯的。GCC在Windows平臺上的編譯效果是無法和VC++相比,利用VC++編譯,內存至少要下降到單獨運行80KB以下。(另外有一種基於LLVM,(低層虛擬機)Clang編譯器編譯效率遠遠優於GCC),在ACM大學生程序設計大賽試題庫中,對不同語言編寫的程序運行時間有嚴格限制,一般說來java編寫的程序一般是其他語言編寫程序運行時長的2倍,越複雜的試題編寫的程序運行時間的差距越大,有的達到3倍,或者4倍,或者5倍。或許有的問題使用java選擇就是個錯誤。對java的態度來說,Google算得上滑稽了,或許,谷歌自以爲他的JVM效率很高,甚至接近C/C++,於是在Andord上全部使用java開發應用,如今,谷歌正悄悄地開發API支持C/C++在Andord上開發應用,稀缺的硬件資源,絕對要高效利用!那麼java好像完敗了。很多鍾情於C/C++的人都覺得Java就像一場龐氏騙局。大企業欺騙了程序員!
或許人們會說:但我們不能這樣要求java,事實上java最大的特點是與平臺無關性。其他的特點有很多語言都比它強N倍。
也許,甲骨文會說,嘿,java是個高效的語言。
當然,爲了獲取高效,Java虛擬機的運行機制也有一個容易被忽略的地方,那些常用的字節碼將被翻譯成本機代碼放在緩存中運行。但是如果應用重新啓動,那麼有將要重新翻譯,另外,只要使用Java虛擬機運行應用就必然會使應用效率低下,即使是利用JIT(即時編譯)一樣要消耗大量資源,而且JIT不像本地化一樣徹底生成機器代碼。所以基本上操作系統,編譯器,數據庫大部分都是C/C++編寫的,一些特大型系統,如航空公式售票系統。還有一個要補充,跨平臺java編程很容易忽視平臺的硬件特徵,結果顯而易見,與硬件的契合度是令人失望的!
難道,我們正的要在跨平臺和效率上做一個取捨嗎?
很多人都會說不,也有人在不斷改進java。
說到這裏,我們回到正題上:怎樣實現跨平臺和高效?
java其實是一個很好的列子,而且java運行效率還是可以的,但是卻不夠,如何實現,這裏我們提出:跨平臺應用程序本地化方案(Cross - platform application localization scheme)(簡稱:CPALS)
意思即是將平臺無關的二進制代碼編譯成本地代碼應用脫離運行時,如Java的Class字節碼文件可以使用這一解決方案生成本地獨立可執行應用,在Windows平臺上生成.exe,應用開發商只需要分發源包jar,無需考慮其他,用戶也不需要考慮效率問題,而且用戶可以自己自定義應用解決方案。
可能存在爭議:既然運行時會解釋,何必多此一舉生成.exe呢。我們可以知道,在生成.exe的獨立可執行文件時,應用的代碼要優化,與操作系統的結合要加深,而且必要時可以增加與硬件的契合度。大幅提高使用效率。Java只是一個列子,對於所有的語言我們都可以如此大幅提高應用的效率。既然有抽象的虛擬化與硬件無關的過程,也有底層化契合硬件的步驟,而且一切交給編譯器優化,我們無需擔心兼容與高效的衝突!

這裏注意的是:CPALS是將利用JVM運行的字節碼轉換爲本地代碼,具有完整的可執行文件格式和系統調度,而不是將源代碼編譯爲本地代碼.如果這樣做,JAVA的存在便沒有多大意義了.

adds:

事實上,也有基於JAVA轉換成本地代碼的編譯程序,但是一般也是另一種形式的虛擬機,姑且不論虛擬機的效率而言,確實比JVM的字節碼效率還是要高一些,畢竟本機操作系統+Runtime的效率還是不成問題,內存是可以降下來的,效率便有了。兼容性與本及代碼,硬件的差距這個問題難以解決啊,虛擬機解決兼容,只有在最小損失下保證最大兼容性纔是解決方案!

我們或許只能在虛擬機的路上走了,不要JAVA的臃腫的虛擬機,而是要比較底層的虛擬機,如LLVM。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章