2016-08-23 90 views
0

在企業應用程序中,相同的代碼運行幾天而沒有重新啓動,並且如果代碼被多次命中,即大於閾值時間,那麼它將會被編譯(大部分),所以我想問爲什麼它不是編譯在第一位..我的意思是jvm工程師可以編譯代碼到字節代碼,以保持平臺獨立性和做一個更多的編譯機器代碼,不應該在一般情況下,機器代碼更快,當它滿足要求被編譯的jit然後jvm可以使用所有的分析信息和統計信息來增強機器代碼並完成所有的增強。當然,這將花費編譯時間,但是通用代碼不是每次都被解釋,而是簡單地執行.i.e創建一個編譯器,它編譯並誇耀它,以防某些方法變熱。我可能在這裏錯了,但這是一個奇怪的問題。爲什麼java解釋代碼是否可以編譯它?

+0

因爲虛擬化有其好處,例如通過反射編程。 此外,關於效率問題,請參閱http://stackoverflow.com/questions/2426091/what-are-the-differences-between-a-just-in-time-compiler-and-an-interpreter –

+0

我我問爲什麼當我們編譯時我們需要解釋..我們可以先編譯成字節碼,然後jvm可以在編譯時立即編譯,所以不需要解釋任何東西。我的意思是他們可以做虛擬化,並在程序開始時進行編譯..雖然它會提高程序的啓動成本 – 1arpit1

+0

那麼,您如何看待Java將處理反射(在運行時查看對象的字段),運行時代理在運行時執行的代碼)和其他類似的功能? –

回答

1

通過優化進行編譯非常昂貴。查看大型C項目(例如firefox,linux內核)的編譯時間,尤其是鏈接時間優化。

JIT也針對目標平臺進行編譯,即他們嘗試使用它們可以支持的所有可用指令進行編譯,這意味着您無法分發已編譯的代碼。

現在考慮JIT執行推測性優化(基於性能分析),這可能會導致錯誤並需要紓困。如果只有編譯是一個選項,這個代碼將不能繼續運行,直到它被重新編譯。通過解釋器,它可以繼續執行導致救援的非常見代碼路徑。

您還必須記住,某些優化是特定於工作負載的,即(不良)測試工作負載可能會運行與真實工作負載不同的代碼路徑,從而受益於在運行時進行配置後進行不同編譯。

並非所有的應用程序都是長時間運行的守護進程。有些東西啓動JVM執行一個任務,然後在完成時退出。

還要考慮很多代碼只運行一次,例如,應用程序啓動或關閉期間。

所有這些因素都有助於爲什麼一些默認情況下,JVM使用組合解釋器+編譯器。其他人可能僅使用AOT編譯的代碼,或者由於技術權衡不同而只能使用解釋器,但通常不會更快。

0

它是多種因素和設計選擇的混合物。

Java以字節碼的形式提供,並且沒有永久性構件依賴於平臺。這是確保平臺獨立性的設計選擇。 Android做出了不同的選擇,主要原因在於它運行的平臺越來越有限。

解釋代碼比編譯和運行一次更快。 所以要有最好的表現與體面的啓動時間。當你確定需要代碼時開始編譯是有效的。編譯是在另一個線程中完成的,一旦準備好就使用二進制文件。當代碼經常使用時,熱點甚至會進行多次重複編譯。它可以使用實際的動態運行時特性,所以二進制比任何只有靜態信息的代碼都快。

0

Java運行大部分代碼,因爲大多數代碼運行速度足夠快,並且不需要承擔本地編譯的開銷。 JIT(HotSpot)引擎將優化高度使用的代碼,在這種情況下,支付是合理的。此外,它將在上下文中優化,這意味着即使變量可能會在理論上發生變化,它也不會在特定的命令序列期間發生,因此序列可以將其放入寄存器或將其保持爲常量。當假設被違反時,JIT將其重新置於解釋模式。提前編譯會失去運行時洞察的所有優勢。 Java的方式實際上產生的代碼比編譯語言(如C++)可以實現的更緊密和更高效。

相關問題