我只是想知道如何擺脫java jre依賴關係並生成本機代碼並將編譯後的代碼作爲應用程序提供?理論上講,我可以得到openJDK JIT,並將我的java代碼編譯爲本地代碼嗎?
那麼這有可能嗎?
P.S.我知道gcj編譯器是它在幹什麼的?
我只是想知道如何擺脫java jre依賴關係並生成本機代碼並將編譯後的代碼作爲應用程序提供?理論上講,我可以得到openJDK JIT,並將我的java代碼編譯爲本地代碼嗎?
那麼這有可能嗎?
P.S.我知道gcj編譯器是它在幹什麼的?
編譯後的字節碼仍然依賴於java虛擬機。 JIT不能在JVM容器外創建「有意義」的代碼。是的,結果是針對目標平臺的一系列有效指令。但是你仍然需要實際的堆棧,堆和垃圾收集器(僅舉幾個必需的構建塊)。
從理論上講,可以爲某種語言使用任何解釋器,並將其轉換爲能夠以該語言生成本地代碼的編譯器。這與一系列稱爲Futamura projections的方程有關。高層次的想法基本上是「欺騙」你如何定義一個編譯器。假設對於某種語言L,我有一個口譯員I(p),假設用L語言編寫的程序p解釋該程序。現在,我假設解釋器I直接用機器代碼表示。進一步假設我有一個叫做mix
的程序,給定一個機器代碼程序和該程序的一個輸入序列,產生一個新的機器代碼程序,該程序是其輸入被固定爲指定輸入的初始程序。例如,如果我編譯這個C++程序:
#include <iostream>
using namespace std;
int main() {
string message;
cin >> message;
cout << message << endl;
}
,然後用於mix
的程序與輸入組合「你好,」我會得到一個程序,它總是打印出消息「Hello」。換句話說,就好像我寫了這個程序:
#include <iostream>
using namespace std;
int main() {
cout << "Hello" << endl;
}
事實證明,它可以建立這個程序。例如,我可以通過查看機器代碼,查看您嘗試從控制檯讀取輸入的每個位置,然後用調用函數的代碼替換該代碼,而不是從硬編碼字符串中讀取。
現在,考慮如果你運行該程序mix
作爲輸入的解釋我和一些程序P會發生什麼。那麼這個結果將是一個機器代碼程序,它等同於我在輸入p上運行的程序。換句話說,你剛剛構建了一個機器代碼程序,它模擬如果你要在程序上運行解釋器會發生什麼 - 這是一個執行程序p的機器代碼程序!
當然,這種結構是完全不切實際的。據我所知,沒有人寫過mix
,如果他們這樣做了,那麼通過將解釋器變成編譯器所做的任何程序都會非常低效,因爲它不會被優化。
至於你最初的問題是關於你是否可以使用JVM的JIT並使用它爲Java程序生成原始機器代碼,我不確定,因爲我沒有看過源代碼,但我強烈懷疑它。機器代碼幾乎肯定包含掛鉤,這些掛鉤會針對特定任務(例如垃圾回收,類加載等)調用回JVM,這會使生成的代碼無法在獨立環境中工作。然而,嘗試這樣做是一個非常酷的想法,我希望這個答案能夠揭示它背後的理論。
Downvoter-你能評論這個答案有什麼問題嗎? – templatetypedef
請注意,這個問題類似於「我可以擺脫Windows並讓我的Windows程序在沒有操作系統的裸機上運行」嗎?
Java程序期望有一大組類可以隨時使用,這是JRE提供的,並且任何編譯器或仿真器也必須提供。
什麼你可以做的不過是看一個發射器,這將允許你把你自己的JRE與您的應用程序 - 這隻會在JRE的平臺上工作,但你已經願意爲特定平臺。有幾個存在 - 我鼓勵你看看堆棧溢出已經有關於如何做到這一點的許多問題。
您是否需要使用Class.forName()構造? –
您可以交付已編譯的代碼,並且可以在安裝了正確版本的Java的任何系統上運行。無論你如何以任何語言進行操作,它都會假設安裝了一些操作系統/軟件。 –
Java運行時可以在本地代碼中處理Class.forName(),只需通過短接預編譯類就可以了,但當然它還必須包含JIT或解釋器,用於未預編譯的類(動態代理,第三方插件等) –