1. 程式人生 > >Java、JVM和作業系統之間的關係,寫給新人,

Java、JVM和作業系統之間的關係,寫給新人,

來張圖:這個帖子寫給新人的,老玩家就直接無視他,因為這個完完全全是白話基礎原理。

解釋:上面的圖是從上往下依次呼叫的關係。

作業系統(Windows/Linux)管理硬體,讓硬體能夠正常、合理的執行,當然各種硬體的驅動實現了作業系統的介面,作業系統呼叫這些介面就能管理硬體,作業系統還像程式設計師提供了一層介面,叫做系統呼叫層,程式設計師可以面向這一層的介面程式設計,來實現對計算機的控制,而不同的作業系統(或者說不同的CPU架構)所提供的介面都是不一樣的,Windows和Linux提供給的那肯定是完全不一樣的,雖然站在最終的角度來看都能實現某一功能。所以同樣一個程式是不能在不同的系統上執行的,甚至可能在同一個系統的不同版本都不一定能完美執行,這就是所謂的平臺相關的程式,比如C/C++程式,然而計算機和網際網路的飛速發展,計算機種類和型號千千萬,作業系統也有很多種類,Window、Linux、iOS等,同樣一款軟體不能不做改變就在不同的作業系統上面執行,這對開發者來說不是很友好。Java語言就能解決這個問題(說成是Java平臺更準確,JVM+JavaAPI),鑑於不同的作業系統所需要的程式是不一樣的,那麼就可以尋找一個方法來解決這個問題,於是JVM就誕生了,又JVM來向下關聯所有作業系統,他能操作所有作業系統,向上提供統一介面,也就是JavaAPI,開發者只需要面向JVM(JavaAPI)程式設計,至於JVM是如何各種不同的作業系統打交道開發者完全不用管,管他是怎麼溝通交流的,於是只要面向JVM+JavaAPI程式設計,一個程式可以在任意作業系統平臺上面執行,這就是所謂的跨平臺,Java程式碼和平臺是無關的,沒有任何關係。---而這,就是Java的跨平臺性質。

  特別指出:也並不是只能面向JavaAPI程式設計,其實也可以掉本地介面,只不過不推薦這樣做,這樣就跟平臺相關了,除非萬不得已,否則就只使用JavaAPI,據我的經驗,還沒見過Java不能解決而需要呼叫本地介面的問題,可能是我才疏學淺。

  其實這個理念跟Linux的shell是一樣的,Linux作業系統管理硬體,Linux向上提供統一介面,而Shell(就等於是上面的JVM)作為命令輸入這和作業系統介面的中間人,中間人會將輸入的命令解釋給作業系統介面來管理和呼叫各種硬體,只不過shell沒有JVM做得那麼徹底,這也就是為什麼對於那麼多不同的shell來說,輸入的命令都基本上是一樣的的道理。我們形象的稱之為“殼”,說白了跟設計模式裡面的門面模式一個道理,讓使用者能控制的都是安全穩定的,有風險的或者不希望使用者觸控得到的就隱藏在門面後面。同事“殼”也能呼叫其他應用,像什麼ls -l,vi,fdisk -l,df -h這種。

  舉個例子:我們國家有很多方言,比如廣東人至聽得懂廣東話,四川人只聽得懂四川話,天津人只聽得懂天津話,這些方言就是所謂的地域相關的語言,對應計算機軟體來說就是平臺相關性,如果我一個北京人要跟廣東、四川和天津人說話,我必須要會說這三種方言,這對於我的語言能力來說很痛苦,要學會這三種話。但是我們知道湖南衛視汪涵很牛逼,會說各種方言,我把他請來當翻譯,汪涵就是JVM,他能說這三種方言,並且他只聽懂得普通話,但是會說各種方言,這好像有點奇怪,所有想要跟廣東、四川和天津打交道的人都跟汪涵說普通話,讓他來幫忙翻譯,我們說一句他翻譯語句,這樣的最終目的我們只需要學會普通話就可以跟任何人交流了。這就是Java平臺。正是因為多了中間翻譯人這麼一個過程,所以很明顯我說普通話跟廣東人交流顯得很慢,需要等汪涵來翻譯,肯定是沒有我直接說廣東話來的直接。這也就是為什麼Java比C/C++慢的原因,虛擬機器需要解釋執行。雖然速度慢,但是換來的是我們只需要說普通話就能跟所有人交流,這樣的代價是值得的,而且虛擬機器效能和各種Java技術的發展,這個解釋執行的過程越來越快,以後說不定就追上C/C++了,也就是汪涵的語速會變得和好聲音華少的語速,甚至再快,到了周杰倫唱歌速度那麼快,我們和不同地區的人交流就更快了。當然現在的JVM不僅僅是逐行解釋執行,還有部分JIT技術和其他很多各方面的提升。

  作業系統的核心是不能夠讓使用者隨便操作的,於是就有了各種應用來操作作業系統核心,比如java應用,各種桌面英勇,所有應用其實都應該叫做shell,只不過一般的應用都有一個很好聽的名字,而Linux就是各種shell,什麼bshell、cshell,shell也是一個應用,只不過很特別,通過指令來控制作業系統核心而不是GUI來控制,就跟Windows環境下的DOS模式差不多。

  題外話,關於我的理解,我們對於計算機的操作,事實上都是對記憶體模型(或者說記憶體的資料結構)在操作,CPU和記憶體的通訊會觸發計算機相關的硬體控制,記憶體變化的時候他會給CPU傳送訊號,然後CPU執行相關的操作顯示到顯示器上面。記憶體首先是建立作業系統的記憶體模型,然後其他記憶體模型都建立在作業系統的記憶體模型之上或者跟作業系統記憶體模型有關。就包括JVM的記憶體模型,當我們操作資料的時候,JVM記憶體模型發生變化,從而控制作業系統,作業系統跟CPU之間完成非常複雜的溝通,然後得出結果,從IO送出訊號。而這一切的一切在計算機內部都是所謂的二進位制在執行,再向下一點,就是無數個高低電平的變化。而我們的程式碼其實就是這些記憶體模型的另一種表示方法,這種表示方法可以讓人很容易看懂和改變。我們平常所謂的記憶體,硬碟這些資料和控制都是邏輯性的,這讓人才容易懂,而轉換到底層就是物理性的。舉個例子:我們平常的String str = "123",我們人看懂,字串str賦值123,那麼當我們在eclipse中輸入String str = "123"點點選Ctrl + S儲存,其實CPU和記憶體之間已經經過了無數次溝通,首先會把"123"轉換成二進位制,從而儲存在硬碟上面的,當我們的JVM開始執行之後,從硬碟把"123"載入記憶體,當我們呼叫str這個引用的時候,記憶體會把"123"在記憶體中的的資料結構通過高低電平傳給cpu,cpu做出運算,控制之後會通過IO,把訊號送到螢幕,當然,還需要經過顯示卡,然後螢幕通過送過來的訊號拉扯液晶,從而螢幕上面顯示"123"字樣。總之一句話,計算機軟體其實就是無數次的改變記憶體模型,我們操作的其實都是記憶體。