java 機器碼 虛擬機_Java虛擬機:源碼到機器碼

無論什么語言寫的代碼,其到最后都是通過機器碼運行的,無一例外。那么對于 Java 語言來說,其從源代碼到機器碼,這中間到底發生了什么呢?這就是今天我們要聊的。

如下圖所示,編譯器可以分為:前端編譯器、JIT 編譯器和AOT編譯器。下面我們逐個講解。

c71fcd42f809fe491173ec29c2ed57d5.png

前端編譯器:源代碼到字節碼

對于 Java 虛擬機來說,其實際輸入的是字節碼文件,而不是 Java 文件。那么對于 Java 語言而言,其實怎么將 Java 代碼轉化成字節碼文件的呢?我們知道在 JDK 的安裝目錄里有一個 javac 工具,就是它將 Java 代碼翻譯成字節碼,這個工具我們叫做編譯器。相對于后面要講的其他編譯器,其因為處于編譯的前期,因此又被稱為前端編譯器。

8f8b94832a13930a45950eecd7096d9b.png

我們運行 javac 命令的過程,其實就是 javac 編譯器解析 Java 源代碼,并生成字節碼文件的過程。說白了,其實就是使用 javac 編譯器把 Java 語言規范轉化為字節碼語言規范。javac 編譯器的處理過程可以分為下面四個階段:

第一個階段:詞法、語法分析。在這個階段,JVM 會對源代碼的字符進行一次掃描,最終生成一個抽象的語法樹。簡單地說,在這個階段 JVM 會搞懂我們的代碼到底想要干嘛。就像我們分析一個句子一樣,我們會對句子劃分主謂賓,弄清楚這個句子要表達的意思一樣。

第二個階段:填充符號表。我們知道類之間是會互相引用的,但在編譯階段,我們無法確定其具體的地址,所以我們會使用一個符號來替代。在這個階段做的就是類似的事情,即對抽象的類或接口進行符號填充。等到類加載階段,JVM 會將符號替換成具體的內存地址。

第三個階段:注解處理。我們知道 Java 是支持注解的,因此在這個階段會對注解進行分析,根據注解的作用將其還原成具體的指令集。

第四個階段:分析與字節碼生成。到了這個階段,JVM 便會根據上面幾個階段分析出來的結果,進行字節碼的生成,最終輸出為 class 文件。

我們一般稱 javac 編譯器為前端編譯器,因為其發生在整個編譯的前期。常見的前端編譯器有 Sun 的 javac,Eclipse JDT 的增量式編譯器(ECJ)。

JIT編譯器:從字節碼到機器碼

當源代碼轉化為字節碼之后,其實要運行程序,有兩種選擇。一種是使用 Java 解釋器解釋執行字節碼,另一種則是使用 JIT 編譯器將字節碼轉化為本地機器代碼。

這兩種方式的區別在于,前者啟動速度快但運行速度慢,而后者啟動速度慢但運行速度快。至于為什么會這樣,其原因很簡單。因為解釋器不需要像 JIT 編譯器一樣,將所有字節碼都轉化為機器碼,自然就少去了優化的時間。而當 JIT 編譯器完成第一次編譯后,其會將字節碼對應的機器碼保存下來,下次可以直接使用。而我們知道,機器碼的運行效率肯定是高于 Java 解釋器的。所以在實際情況中,為了運行速度以及效率,我們通常采用兩者相結合的方式進行 Java 代碼的編譯執行。

ca25b751a1be90a07d2bcf15357840c7.png

在 HotSpot 虛擬機內置了兩個即時編譯器,分別稱為 Client Compiler 和Server Compiler。這兩種不同的編譯器衍生出兩種不同的編譯模式,我們分別稱之為:C1 編譯模式,C2 編譯模式。

注意:現在許多人習慣上將 Client Compiler 稱為 C1 編譯器,將 Server Compiler 稱為 C2 編譯器,但在 Oracle 官方文檔中將其描述為 compiler mode(編譯模式)。所以說 C1 編譯器、C2 編譯器只是我們自己的習慣性稱呼,并不是官方的說法。這點需要特別注意。

b851f00940d5fa9ec8999b30629720f1.png

那么到底應該選擇 C1 編譯模式還是 C2 編譯模式呢?

實際上對于 HotSpot 虛擬機來說,其一共有三種運行模式可選,分別是:

混合模式(Mixed Mode) 。即 C1 和 C2 兩種模式混合起來使用,這是默認的運行模式。如果你想單獨使用 C1 模式或 C2 模式,使用 -client 或 -server 打開即可。

解釋模式(Interpreted Mode)。即所有代碼都解釋執行,使用 -Xint 參數可以打開這個模式。

編譯模式(Compiled Mode)。 此模式優先采用編譯,但是無法編譯時也會解釋執行,使用 -Xcomp 打開這種模式。

在命令行中輸入 java -version 可以看到,我機器上的虛擬機使用 Mixed Mode 運行模式。

5396f17194681c46a71b4614575380ab.png

寫到這里,我們了解了從 Java 源代碼到字節碼,再從字節碼到機器碼的全過程。本來到這里就應該結束了,但在我們 Java 中還有一個 AOT 編譯器,它能直接將源代碼轉化為機器碼。

AOT編譯器:源代碼到機器碼

AOT 編譯器的基本思想是:在程序執行前生成 Java 方法的本地代碼,以便在程序運行時直接使用本地代碼。

但是 Java 語言本身的動態特性帶來了額外的復雜性,影響了 Java 程序靜態編譯代碼的質量。例如 Java 語言中的動態類加載,因為 AOT 是在程序運行前編譯的,所以無法獲知這一信息,所以會導致一些問題的產生。類似的問題還有很多,這里就不一一舉例了。

總的來說,AOT 編譯器從編譯質量上來看,肯定比不上 JIT 編譯器。其存在的目的在于避免 JIT 編譯器的運行時性能消耗或內存消耗,或者避免解釋程序的早期性能開銷。

在運行速度上來說,AOT 編譯器編譯出來的代碼比 JIT 編譯出來的慢,但是比解釋執行的快。而編譯時間上,AOT 也是一個適中的速度。所以說,AOT 編譯器的存在是 JVM 犧牲質量換取性能的一種策略。就如 JVM 其運行模式中選擇 Mixed 混合模式一樣,使用 C1 編譯模式只進行簡單的優化,而 C2 編譯模式則進行較為激進的優化。充分利用兩種模式的優點,從而達到最優的運行效率。

總結

在 JVM 中有三個非常重要的編譯器,它們分別是:前端編譯器、JIT 編譯器、AOT 編譯器。

前端編譯器,最常見的就是我們的 javac 編譯器,其將 Java 源代碼編譯為 Java 字節碼文件。JIT 即時編譯器,最常見的是 HotSpot 虛擬機中的 Client Compiler 和 Server Compiler,其將 Java 字節碼編譯為本地機器代碼。而 AOT 編譯器則能將源代碼直接編譯為本地機器碼。這三種編譯器的編譯速度和編譯質量如下:

編譯速度上,解釋執行 > AOT 編譯器 > JIT 編譯器。

編譯質量上,JIT 編譯器 > AOT 編譯器 > 解釋執行。

而在 JVM 中,通過這幾種不同方式的配合,使得 JVM 的編譯質量和運行速度達到最優的狀態。

原文:https://www.cnblogs.com/zuotongbin/p/11715396.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/534235.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/534235.shtml
英文地址,請注明出處:http://en.pswp.cn/news/534235.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

docker 遠程連接 文件看不到_開發提升十倍生產力: IDEA 遠程一鍵部署 Spring Boot 到 Docker...

一、開發前準備二、新建項目《Java 2019 超神之路》《Dubbo 實現原理與源碼解析 —— 精品合集》《Spring 實現原理與源碼解析 —— 精品合集》《MyBatis 實現原理與源碼解析 —— 精品合集》《Spring MVC 實現原理與源碼解析 —— 精品合集》《Spring Boot 實現原理與源碼解析…

java多臺_Java 多態

Java中多態的特性,在學習中就是很難懂,比較抽象的概念。學的時候就犯糊涂,但日后會發現,基礎在日常工作的理解中占有重要的角色。下面,我將用一個代碼實例,回憶和鞏固多態的概念和存在的意義。理解多態&…

快準牌電腦發軟件_做自媒體必備技能,視頻剪輯軟件排名(精品篇)

作者:老馬引流定位:專業專注引流推廣0X00 前言毫不客氣的說,視頻正日益成為社交媒體和營銷的重要組成部分,有越來越多的人參與到視頻剪輯當中來,而其中最為關鍵的就是視頻剪輯軟件。而市面上的視頻剪輯軟件當然也是五花…

ad電阻原理圖_【雕爺學編程】Arduino動手做(2)---光敏電阻模塊

【Arduino】108種傳感器模塊系列實驗(02)實驗二:光敏電阻傳感器模塊我手里這塊是三針版的,挺秀氣吧光敏電阻是用硫化隔或硒化隔等半導體材料制成的特殊電阻器,其工作原理是基于內光電效應。光照愈強,阻值就…

java從url下載文件_Java從URL下載文件

在這篇文章中將學習如何從java下載URL中的文件。使用java.net.URL openStream()方法從java程序中的URL下載文件。也可以使用Java NIO Channels或Java IO InputStream從URL打開流中讀取數據,然后將它保存到文件中。下面是從指定URL下載的簡單Java程序。它演示了如何在…

怎么判斷一個字符串的最長回文子串是否在頭尾_LeetCode 第 131 號問題:分割回文串...

題目來源于 LeetCode 上第 131 號問題:分割回文串。題目難度為 Medium,目前通過率為 45.8% 。題目描述給定一個字符串 s,將 s 分割成一些子串,使每個子串都是回文串。返回 s 所有可能的分割方案。示例:輸入題目解析首先&#xff0…

java的地位_Java地位無可動搖的12個原因

如今,面對曾經在程序員中被各種新技術掩蓋直至堙滅的技術值得懷念。猶如COBOL這當年被老程序員們尊為神器的語言如今也基本沒有價值。而Java作為現代程序員的中堅力量在這點上會不會成為下一個COBOL?有關JAVA的技術賣出多少本書已經是一個很久遠的記憶了…

hystrix threadpool coresize_Hystrix斷路器 - 求知若渴的蝸牛

Hystrix介紹在微服務場景中,通常會有很多層的服務調用。如果一個底層服務出現問題,故障會被向上傳播給用戶。我們需要一種機制,當底層服務不可用時,可以阻斷故障的傳播。這就是斷路器的作用。他是系統服務穩定性的最后一重保障。在…

ionic保存到mysql_ionic sqlite 存取數據封裝(兼容真機與webkit瀏覽器)

不管是真機還是H5,都有提供sqlite數據庫進行存儲數據。那么我們只要封裝好函數就能隨意調用了。如果只是存儲簡單的鍵值對形式的話,ionic官網也提供了一個兼容網頁的storage,https://ionicframework.com/docs/storage,但只能key/v…

sql plus 表的總記錄數是多少_直播回顧 | 億級并發絲毫不虛,TDSQL-SQL引擎是如何煉成的...

騰訊云數據庫國產數據庫專題線上技術沙龍正在火熱進行中,3月19日唐顥的分享已經結束,沒來得及參與的小伙伴不用擔心,以下就是直播的視頻和文字回顧。關注“騰訊云數據庫”公眾號,回復“0319唐顥”,即可下載直播分享PPT…

java plug機制_插件機制 - OpooPress - 基于 Java 的靜態博客生成器

插件機制通過插件機制可以很容易的擴展 OpooPress 博客系統的功能。 Plugin 定義如下public interface Plugin{/**** param registry*/void initialize(Registry registry);}Registry 接口定義如下:public interface Registry {Site getSite();void registerConvert…

運放放大倍數計算公式_19.運算放大器的特性與應用,不得不掌握的知識點(一)...

運算放大器,簡稱“運放”,是電力電子中最重要的器件之一,主要作用為:信號放大、信號運算、信號處理、波形的產生和變換。一、運算放大器的內部結構集成運算放大器內部結構集成運算放大器內部一般由四個單元組成,各單元…

java選項設置_java環境配置

javac無法執行檢查:看看java 相關的java相關路徑有沒有多余的符號,比如多出分號,逗號(筆者上面是正確的路徑展示形式)Win10下 Java環境變量配置首先,你應該已經安裝了 Java 的 JDK 了(如果沒有安裝JDK,請跳轉到此網址&…

teleport 組件的作用_人臉識別綜述! 覆蓋人臉檢測,預處理和特征表示三大核心組件!...

The Elements of End-to-end Deep Face Recognition: A Survey of Recent Advances 人臉識別是計算機視覺社區中最基礎和歷史悠久的話題之一。隨著深度卷積網絡和大尺度數據集發展,深度人臉識別取得極大進步并且應用到許多領域。給定一個自然圖像或者視頻幀作為輸入…

itunes未能連接到iphone_iTunes下載_蘋果iTunes官方下載「32位|64位」

iTunes是蘋果官方推出的Apple官方數字媒體播放與管理應用程序。蘋果iTunes官方下載中文版能將您所有的媒體文件和應用收藏導入iPad和iPhone,您還可以通過它購買應用、數字音樂、視頻、電視及游戲等等。iTunes是目前最專業的iPad和iPhone管理應用工具。本站提供蘋果i…

java短視頻上傳阿里云流程_短視頻上傳

啟動上傳前需要設置上傳回調,需要實現VODSVideoUploadCallback回調:vodsVideoUploadClient.uploadWithVideoAndImg(vodSessionCreateInfo, new VODSVideoUploadCallback() {Overridepublic void onUploadSucceed(String videoId, String imageUrl) {//上…

feko軟件_計算電磁學各種方法和電磁仿真軟件簡述

計算電磁學中有眾多不同的算法,如時域有限差分法(FDTD)、時域有限積分法(FITD)、有限元法(FE)、矩量法(MoM)、邊界元法(BEM)、 譜域法(SM)、傳輸線法(TLM)、模式匹配法(MM)、橫向諧振法(TRM)、線方法(ML)和解析法等等。在頻域,數值算法有:有限…

出租車管理系統java_基于jsp的出租車管理系統-JavaEE實現出租車管理系統 - java項目源碼...

基于jspservletpojomysql實現一個javaee/javaweb的出租車管理系統, 該項目可用各類java課程設計大作業中, 出租車管理系統的系統架構分為前后臺兩部分, 最終實現在線上進行出租車管理系統各項功能,實現了諸如用戶管理, 登錄注冊, 權限管理等功能, 并實現對各類出租車管理系統相…

cad常青藤插件_原來還有這么好用的CAD插件,半小時就能做完一張圖

作為一名優秀的設計師或者建筑師,如果你沒用過逆天的CAD插件,我覺得不行,所以下面小編就給大家推薦幾個非常好用的CAD插件,希望可以幫助大家大幅提升工作效率。接下來小編就帶大家一起看看吧!1、天正建筑天正建筑顧名思…

java 停止線程播放音頻_Notification?播放?關閉?聲音----轉載

NotificationPlayer.java定義一個播放Notification聲音的player,本質上仍然是一個MediaPlayer,這個是多線程編程的很好的例子public class NotificationPlayer implements OnCompletionListener {//發送播放和停止的cmdprivate static final int PLAY 1…