Java能不能像C語言不通過JVM虛擬機直接編譯成二進制機器碼,讓計算機直接運行?

小松語錄


從語言設計的角度看是可以的,重新設計一下編譯器就能實現,但從工程實踐的角度看是不可行的。

其一,Java語言最大的特點就是跨平臺可移植,一次開發,一次編譯,多平臺執行,這一特性就是靠JVM(Java虛擬機)實現的,如果改寫編譯器像C語言一樣直接編譯成了可執行程序,就失去了跨平臺特性。

其二,Java語言設計之初就設計成為了一款嚴重依賴JRE(Java運行時環境)的語言,有部分語言設計上的缺陷必須依賴JVM來解決,比如GC(垃圾回收),我們知道,Java語言是沒有內存回收能力的,因此還得靠JVM,在工程實踐中,如果軟件不能進行內存回收,後果將是災難性的。

其三,Java語言是面向對象的,區別於同是面向對象的C++,Java還有一個動態特性。

它允許程序動態地裝入運行過程中所需要的類,這是C++語言進行面向對象程序設計所無法實現的。在C++程序設計過程中,每當在類中增加一個實例變量或一種成員函數後,引用該類的所有子類都必須重新編譯,否則將導致程序崩潰。Java從如下幾方面採取措來解決這個問題。Java編譯器不是將對實例變量和成員函數的引用編譯為數值引用,而是將符號引用信息在字節碼中保存下傳遞給解釋器,再由解釋器在完成動態連接類後,將符號引用信息轉換為數值偏移量。這樣,一個在存儲器生成的對象不在編譯過程中決定,而是延遲到運行時由解釋器確定的。這樣,對類中的變量和方法進行更新時就不至於影響現存的代碼。解釋執行字節碼時,這種符號信息的查找和轉換過程僅在一個新的名字出現時才進行一次,隨後代碼便可以全速執行。在運行時確定引用的好處是可以使用已被更新的類,而不必擔心會影響原有的代碼。如果程序連接了網絡中另一系統中的某一類,該類的所有者也可以自由地對該類進行更新,而不會使任何引用該類的程序崩潰。而這一切同樣依賴JRE。

以上幾點決定了Java不能像C語言一樣直接編譯成機器碼,當然,還有一些其它因素,但我認為上面幾點是最主要的。


ScienceTech365


C語言的編譯過程如下:

C源程序-->預編譯處理(.c)-->編譯、優化程序(.s、.asm)-->彙編程序(.obj、.o、.a、.ko)-->鏈接程序(.exe、.elf、.axf等),如圖1所示。其實編譯裡面還包括詞法分析、語法分析、語義分析,就不展開說了。

而Java的執行可以分為兩大步驟,如圖2所示,第一是編譯,這一過程就是調用的javac命令,編譯成對應的.class文件。第二是解釋執行,這一過程是調用的java命令,其實我理解的是調用了Java裡的jvm,即java虛擬機。JVM其實計算機把高級語言解析成機器碼都會存在一個類似這樣的中間件。在c#中,我知道先編譯成CIL託管代碼,然後Jit編譯器在CLR(公共語言運行時)這樣一個庫下把託管代碼解釋成可執行文件.exe或者dll。現在我就把JVM看作是JIT編譯器。把要執行的代碼翻譯給計算機聽,然後機器執行,大致也就是這麼個道理。當然了Java程序還是通過解釋器進行解釋執行時,當JVM發現某個方法或代碼塊運行特別頻繁的時候,就會認為這是“熱點代碼”(Hot Spot Code)。然後JIT會把部分“熱點代碼”翻譯成本地機器相關的機器碼,並進行優化,然後再把翻譯後的機器碼緩存起來,以備下次使用。總的來說還是需要JVM。

如果你想把Java編譯成二進制機器碼,那要重新開發一個編譯器,將Java源代碼通過編譯(包括詞法分析、語法分析、語義分析,中間代碼,優化等)生成彙編語言,然後再轉化成機器碼。這樣以來,每個平臺(X86,ARM,MIPS,PowerPC等)都需要重新編譯生成相應平臺的機器碼,而且如果沒有JVM,就沒有GC(垃圾自動回收)功能了。




鼴鼠科技


肯定是可以的,而且目前就有成熟的解決方案,不過,在回答這個問題之前,需要先明確一點,就是為什麼Java 需要JVM虛擬機?然後再來討論可行的實現方案。


Java 為什麼需要JVM

眾所知周,Java 是跨平臺的,能夠實現程序代碼的“一次編譯,到處運行”,無論在哪個操作系統上,Java 代碼都會被編譯為統一的Java 字節碼文件,然後再交由JVM虛擬機來運行;Java 程序員只要編寫一套程序,便同時能在Linux,Windows和Mac x等不同操作系統上運行,JVM在其中扮演了一個不可或缺的重要角色。

不同操作系統的實現方式不一,各個操作操作都有自己的一套處理方式和規範,Java 的跨平臺功能就是基於不同操作系統實現不同JVM,在哪個操作系統上運行就調用哪個操作系統的JVM來運行Java 程序。

正式由於JVM虛擬機的存在,Java 跨平臺才得以實現,也才會有那麼多的企業、組織和開發者青睞Java 語言,讓Java 語言二十多年來長盛不衰,更是有衍生了不少除Java 之外的,基於JVM運行的優秀編程語言,比如:Kotlin、Scala、Groovy、Clojure、Ceylon等。



GCJ

GCJ 是GNU Compiler for the Java Programing Language 的簡稱,翻譯過來就是“為Java 語言實現的GNU編譯器”,GCJ編譯工具就包含在包含在GCC中,只要下載了GCC,就能使用GCJ。

使用GCJ編譯工具可以把Java 源程序編譯為字節碼文件,也能將Java 字節碼文件編譯為本地機器碼,更是能實現Java 源程序直接編譯為本機可運行的本地機器碼。而本地機器碼就可在本機直接運行。


GraalVM

GraalVM 是甲骨文公司開發的一個基於JVM的、支持多語言的高性能虛擬機,GraalVM中提供的native-image組件就能實現將Java 源程序直接編譯為本機可運行的本地機器碼,就可以在本機直接運行。

不僅是Java,GraalVM支持的語言還有C/C++、Rust、JS、Python、R、Ruby等語言,可謂是一個全棧語言虛擬機。


方舟編譯器

最後一個是華為的方舟編譯器,華為開發方舟編譯器的目的就是為了解決JVM虛擬機性能較低的問題。方舟編譯器支持Java、Kotlin、C/C++、JS等語言,目前方舟編譯器實現了部分開源,代碼託管在Gitee、華為官方代碼庫。


方舟編譯器前端接收Java、Kotlin、C/C++、JS的語言的源程序,然後將其轉換為中間語言IR,然後再交給後端,最終生成本機可運行的二進制文件。


完結,希望以上回答對你能有所幫助。


分享到:


相關文章: