問題一:Java與C++區別
1.Java需要運行時環境,包括Java虛擬機以及Java核心類庫等。
2.C++無需額外的運行時,通常編譯后的代碼可以讓機器直接讀取,即機器碼
問題一:Java為什么要在虛擬機運行?
1.一次編譯,到處運行。
這里涉及到一個概念:字節碼。
Java字節碼指的是設計一個面向Java特性的虛擬機,通過編譯器將Java程序轉換成該虛擬機所能識別的指令序列。
為什么是叫字節碼呢?原因還是Java 字節碼指令的操作碼(opcode)被固定為一個字節。
2.托管環境。
虛擬機能夠代替我們處理一些代碼中冗長而且容易出錯的代碼的部分,比如C++中經常出現的垃圾回收問題,程序員經常忘記回收垃圾。
另外,虛擬機還為我們提供了如數組越界,動態類型等動態檢測,極大地降低了Java開發的難度。
問題二:Java虛擬機具體是如何運行Java字節碼的?
以Hotspot虛擬機為例子,Java虛擬機細分為方法區、堆、Java方法棧、面向本地方法的本地方法棧、PC寄存器
從虛擬機的視角看,
1.執行Java代碼首先需要將它編譯成class文件加載到Java虛擬機中,加載后的Java類會被保存到方法區中。實際運行時,虛擬機會執行方法區中的代碼。
2.上圖中的堆和棧是用來存儲運行時數據的。其中,棧被分成了面向Java方法的Java方法棧和面向本地方法(C++寫的native方法)本地方法棧,以及存放各個線程執行位置的PC寄存器
3.在運行過程中,每當調用一個方法,虛擬機就會在當前線程的Java方法棧中生成一個棧幀,用以存放局部變量以及字節碼的操作數。當方法執行完畢之后,該棧幀也隨着被彈出。
從硬件角度看,
在HotSpot里面,編譯Java代碼有兩種方式,一種是解釋執行,另一種是編譯執行。
解釋執行:逐條將字節碼翻譯成機器碼並執行(邊翻譯邊讀)
編譯執行:將一個方法中包含的所有字節碼編譯成機器碼之后執行。(翻譯完之后,再讀)
前者優勢在於:無需等待編譯完全
后者優勢在於:熱點代碼比較多的時候,讀取的執行效率快於前者。
HotSpot使用的是多個即時編譯器共同協作:C1,C2,和Java10正式使用的Graal。
參考文章:《極客時間》-https://time.geekbang.org/column/article/11289