2008-09-07 89 views
38

看起來你可以用字節碼做任何事情,你可以在本地代碼中簡單快速地完成任務。從理論上講,甚至可以通過在字節碼中分發程序和庫,然後在安裝時編譯爲本地代碼而不是JITing,來保持平臺和語言的獨立性。字節碼優於本地代碼的優點是什麼?

所以一般來說,你想要什麼時候執行字節碼而不是本地的?

回答

31

來自SGI漢克Shiffman表示(很久以前的事,但它的直到是):

Java有三個優點 使用字節碼而不是去 系統的本地代碼:

  1. 便攜:每種計算機都有其獨特的指令集 。雖然某些處理器包含針對其前身 的 指令,但在一種計算機 上運行的程序 通常不會在其他任何程序上運行。在 中增加了運行提供的服務 系統,其中每個系統描述的是 自己的獨特方式,並且你有一個 的兼容性問題。一般來說,你的 不能編寫和編譯一個程序 一種系統並運行在任何其他 其他沒有很多工作。通過在 應用程序和真實環境 (計算機+操作系統)之間插入 虛擬機,Java得到 圍繞此限制。如果 應用程序編譯成Java字節碼 以及字節碼解釋 每個環境中以同樣的方式再 你可以寫一個程序, 將在所有地方支持的Java不同 平臺上工作。 (這是理論,反正在 實踐總是有小 不兼容性趴在等待 程序員。)

  2. 安全:一個Java的優點之一是其整合到Web。加載 一個網頁,使用Java到您的 瀏覽器和Java代碼是 自動下載並執行。 但是,如果代碼破壞文件, 是通過程序員的惡意還是sloppiness ? Java 通過阻止潛在的危險操作阻止下載的小應用程序執行任何破壞性操作。 它允許代碼運行它之前 檢查它試圖繞過 安全性。它驗證數據是否始終如一地使用 :代碼 在一個階段將數據項作爲整數 操作,然後嘗試使用它,因爲稍後將捕獲指針並阻止其執行 。 (Java的 語言不允許指針 運算,所以你不能編寫Java代碼 做我們剛纔所描述的。 但是,沒有什麼自己使用十六進制 防止 有人編寫破壞性字節 碼編輯器甚至建立一個Java字節 代碼彙編器。)它通常不是 可能在執行前分析程序的 機器代碼,並且 判斷它是否做任何事情 不好。像寫 自我修改代碼這樣的竅門意味着操作可能不會存在,直到 稍後。但是對於這種驗證,Java字節碼被設計爲 :其 沒有指示 惡意程序員將用來隱藏 他們的攻擊。

  3. 大小:在微處理器世界中,RISC通常優於CISC上的 。最好有一個小的指令集 ,並使用許多快速的 指令來完成一項工作,而不是使用 許多複雜的操作作爲 單一指令。 RISC設計 需要更少的芯片上的門到 實施他們的指令,允許 有更多的空間管道和其他 技術使每個指令 更快。然而在翻譯中, 這些都不重要。如果你想爲 實現單條指令,對於 switch語句的變量 長度取決於條件數 從句,沒有理由不去做 等等。事實上,複雜指令集 是一個基於Web的 語言的優勢:它意味着同樣的 程序將會更小(更大的複雜性較少 指令), 這意味着更少的時間在我們的速度 - 轉移 有限的網絡。

因此,考慮字節碼VS本土時,考慮你想可移植性,安全性,尺寸和執行速度之間做出哪些權衡。如果速度是唯一重要的因素,那就去當地。如果其他任何人更重要,請使用字節碼。

我還會補充說,爲每個發行版維護一系列操作系統和基於體系結構的目標編譯代碼可能會變得非常繁瑣。在多個平臺上使用相同的Java字節碼並使其「僅工作」是一個巨大的勝利。

+4

4年後......可移植性:產生本地代碼的編譯器可以交叉編譯,就像gc(官方的[Go](http://golang.org/)編譯器),這使得它很簡單。安全性:[Native Client](https://developers.google.com/native-client/)在沙盒中運行本地代碼,從而限制其權限。大小:現在很少成爲問題,即使是移動設備也是如此。 – 2012-08-01 14:08:02

2

我想你只是回答了你自己的問題:平臺獨立性。與平臺無關的字節碼被生成並分發到其目標平臺。在執行之前,它可以在執行開始之前或同時快速編譯爲本地代碼(Just In Time)。 Java JVM和據推測.NET運行時按照這個原則運行。

9

字節碼創建額外的間接級別。

間接的這種額外層次的優點是:

  • 平臺獨立性
  • 可以創建任意數量的編程語言(語法),並讓它們向下編譯到相同的字節。
  • 可以輕鬆創建跨語言轉換器
  • x86,x64和IA64不再需要編譯爲單獨的二進制文件。只有正確的虛擬機需要安裝。
  • 每個操作系統只需要創建一個虛擬機,它將支持同一個程序。
  • 只要及時編譯,您就可以通過替換單個修補源文件來更新程序。 (非常有利的網頁)

一些不足之處:

  • 性能
  • 更容易反編譯
1

理想情況下,您可以使用便攜式字節碼將本地代碼即時編譯。我認爲字節碼解釋器存在沒有JIT的原因主要是由於本地代碼編譯增加了虛擬機的複雜性這一實際事實。構建,調試和維護該附加組件需要時間。並非每個人都有時間或資源來做出這一承諾。

次要因素是安全性。驗證解釋器不會崩潰比保證本地代碼相同要容易得多。

三是表現。生成機器碼通常需要更多的時間,而不是僅爲只運行一次的小塊代碼解釋字節碼。

15

基本上任何程序的性能都會提高,如果它被編譯,執行分析,並且結果反饋回編譯器第二遍。實際使用的代碼路徑會更積極地進行優化,循環展開到正確的程度,並且熱指令路徑排列爲最大化I $命中。

所有不錯的東西,但它幾乎從來沒有完成,因爲它經歷了很多步驟來構建二進制文件令人討厭。

這是在將代碼編譯爲本地代碼之前運行一段時間的優點:配置信息自動可用。 Just-In-Time編譯之後的結果是針對程序正在處理的特定數據的高度優化的本地代碼。

能夠運行字節碼也可以實現比靜態編譯器可以安全使用的更積極的本機優化。例如,如果一個函數的參數中的一個參數始終爲NULL,那麼對於該參數的所有處理可以簡單地從本機代碼中省略。將在函數序言中對參數進行簡短的有效性檢查,如果該參數不爲NULL,則VM將中止返回字節碼並再次開始分析。

3

所有很好的答案,但我的熱鍵已被擊中 - 表現。

如果正在運行的代碼花費所有時間調用庫/系統例程 - 文件操作,數據庫操作,發送窗口消息,那麼如果它被打亂,則無關緊要,因爲大部分時間都用在等待爲那些較低級別的操作完成。

然而,如果代碼中包含的東西,我們通常所說的「算法」,即必須要快,不要花太多的時間通話功能,如果這些不經常使用足以成爲一個性能問題,那麼JIT是非常重要的。

0

可移植性和平臺獨立性可能是字節碼相對於本機代碼最顯着的優勢。