每個程序員都該瞭解的JVM - JAVA虛擬機介紹
February 14, 2020JAVA虛擬機介紹
這篇是關於JVM的High Level介紹 我們會介紹
虛擬機歷史
虛擬機命名理由
虛擬機大概念
虛擬機流程圖
準備好踏上理解艱澀JVM的旅程了嗎 Let’s go!
前世今生
1991年 太陽電腦(Sun MicroSystems, 2010年被Oracle收購)想要開發可以操控智慧型家電(微波爐 電視機)或是讓智慧型家電彼此溝通的新技術 於是設立了一個團隊來研發 並把這個計畫稱為綠色計畫(Green Project)
這個計畫難是難在對象是家電 有許多的限制如下
1.嵌入式系統的記憶體少:所以程式必須盡可能消耗少點的記憶體
2.跨平台性:我們不想要一個程式寫完後 拿到每個裝置去編譯才能執行 我們希望編譯一次 到處執行
3.安全性:程式在裝置間傳輸的過程 即使被惡意修改 也要確保裝置不會損壞
4.多線程支援
編譯器
最初 團隊打算使用C++ 但是C++無法達到跨平台的要求 比如說你在Linux系統編譯得到的Hello.exe不能直接拿到Window執行
所以雖然C++在當時非常普及 但因為不符合要求 首先淘汰
直譯器
也許你會說 要跨平台還不簡單 我用直譯器就好啦
直譯器可以讓你的高階語言不需經過編譯器 每跑一行就執行一行 比如說常聽到的Python跟Ruby 都是使用直譯器
所以只要每個裝置都有我的程式語言的直譯器 就可以達到跨平台啦
但眾所皆知的 直譯器很慢 很慢 非常慢 因為他每跑一行才執行一行 有些編譯器做的最佳化它都不能做
那有沒有辦法又跨平台 又快呢 簡單 參在一起做撒尿牛丸
編譯器+直譯器
Hello.class裡面存的就是Java bytecode 當然這個bytecode的格式我們會有另一個章節來介紹 現在你可以想成是C裡面的機器語言bytecode
bytecode是被編譯 壓縮並且最佳化過的 這樣跑起來就快多了 然後再把bytecode丟給每個平台專屬的JVM 他就會隨著硬體跟作業系統的不同做不一樣的處理 得到一樣的結果
這就是JAVA如何達成跨平台 不過當時想出這個方法的時候這個語言還不叫Java 叫做Oak
綠計畫後續
發明出Oak之後 原本想把這個語言用在電視機 電話等家電上面 但最後結論是這個語言太強 會給電視的使用者太多權限 而且當時對於智能家電的需求根本就不高 結果綠計畫胎死腹中
1994年 綠計畫一夥人發現當紅的全球資訊網world wide web的中心思想跟他們一開始對家電的想法很接近 都是資料在裝置之間傳來傳去 於是就把他們新發明的語言改名為Java 並寫了一個小型全球資訊網瀏覽器HotJava 1995年在SunWorld大會上公布了這個改變軟體生態已經30年的程式語言
比較重要的名字 是James Gosling 人稱Java之父 就是綠計畫的一員
JAVA問世之後 大家發現Java的風格跟C++挺像的 都是面向對象的語言 但Java沒有C++裡頭繁瑣的指針pointer 改成引用reference 還移除多重繼承 並增加垃圾回收的功能 最重要的當然就是一次編寫 到處運行的特性
1998年 推出JDK1.2 改名為Java 2 Platform 不僅如此 還相當有野心 連推三個版本
J2SE 標準版 進攻Desktop
J2EE 企業版 進攻伺服器
J2ME 微型版 進攻機上盒 行動電話和PDA
多麼有遠見 基本上目標就是 有一個方向成功就從此一帆風順
可想而知 最成功的就是J2EE 搭上互聯網順風車 所有特性都符合物聯網的伺服器需求
跨平台 安全 快 容易使用(面向對象)
開發者數目快速擴張 一些支持C語言的巨頭都紛紛表示有興趣 其中IBM更是其中霸主 快速推出網頁伺服器WebSphere 再推出一個巨砲IDE - Eclipse 加上自身早就很強的硬體 直接一條龍的產品線(硬體+軟體+伺服器) IBM當時的三駕馬車完全就有如十年前谷歌的三駕馬車(MapReduce, BigTable, GFS) 直接營收一飛沖天
之後不少異軍突起 想佔領伺服器的這塊大餅 比較有名的就是Ruby on rails跟PHP 但基本對Java構不成太大威脅
2006年Hadoop橫空出世 底層也是使用Java來完成map/reduce 此後海量數據的運算崛起也助了Java一臂之力
2008年Android降臨地表 Google的大力支持 讓Java再度來到前所未有的高峰
2020年 每個程序員都要懂的JVM 粉墨登場 讓大家對於Java底層的未知領域一清二楚 降低了Java 30年來學習的門檻 揭開了JVM長年以來的神秘面紗
那為什麼JAVA虛擬機要叫JAVA虛擬機
我看了很多關於虛擬機的書 幾乎沒有人回答這個問題 我認為要先了解這個問題的答案 對於之後的理解有極大的幫助
首先 要先知道什麼是虛擬機 顧名思義 虛擬機就不是實體機器 他是用軟體模擬(實作)一個具有完整功能的硬體 這個模擬硬體的東西就叫虛擬機 虛擬機可以像實體機器一樣執行程式
用日常生活的例子 即使你買的是Window的電腦 你也常聽到有人用虛擬機安裝Linux的作業系統 安裝完後你就可以在虛擬機中執行Linux的程序指令 就好像再用Linux一樣 你完全不用管實際底層到底是什麼硬體
鋪梗鋪得有點明顯 看到上面一段你大概知道下一段要接什麼了 沒錯!這個理念跟我們的跨平台根本一模一樣 所以JAVA也用了跟虛擬機一樣的理念 不管你的底層是什麼硬體什麼作業系統 只要你有了Java虛擬機 你就可以在Java虛擬機中執行java bytecode 你完全不用管實際底層到底是什麼硬體
所以你寫java 你編譯java不是為了要讓你的程序跑在特定Linux或是某台Window上 你是為了要讓你的程序跑在JVM上
原來虛擬機這麼方便
但為了要達成這個 編寫一次 到處執行 JVM必須要有很嚴謹的規範 才能更讓每一個不同機器上的JVM拿到一樣的bytecode跑出一樣的結果
JAVA 虛擬機三個概念
規範 實作 跟 運行時實例
規範(specification):
所有人寫Java程式不再需要考慮是在哪個機器上或是作業系統上跑 只需要對JVM編寫 要達成這個目的 就有許多嚴格的要求必須遵守 Oracle發布的Java Virtual Machine Specification就是所有要實作JVM的人必須要遵守的規範 只要你照著規範走 任何人都可以實作自己的虛擬機
實作(implementation):
有規範就有實作 其中實作的最有名的就屬以下兩位仁兄
Oracle HotSpot JVM
IBM’s JVM
(你在你的終端機輸入 java -version 就可以看到你的虛擬機是誰實作的)
運行時實例(runtime instance):
有實作就有運行時實例 當你在執行 java Hello的時候 一個JVM的instance就會被創建在記憶體裡面 然後開始加載Hello文件
注意每一個運行時實例只會跑一個java應用 所以要是你在終端機連輸入五次java Hello 會生出五個運行時實例去跑五個程式
JVM 架構
下圖是組成一個JVM的所有主要元件
不用擔心 我們會討論所有的元件 讓JVM從此不再可怕