架構師視角:對JVM架構進行解析

每一個Java 開發(fā)人員都知道字節(jié)碼由JRE (Java運行時環(huán)境)執(zhí)行。但許多人不知道JRE是Java虛擬機(JVM)的實現(xiàn), 它負責分析字節(jié)碼、解析并執(zhí)行代碼。作為一個開發(fā)人員了解JVM架構是非常重要的,因為它使我們能更高效的編寫代碼。在這篇文章中我們將更深入了解Java中的JVM架構以及JVM的各個組件。

JVM是什么?

虛擬機 是物理機器的一個軟件實現(xiàn)。Java運行在VM上,實現(xiàn)WORA (一處編寫,處處運行)。 編譯器將Java文件編譯成Java .class 文件,然后這個.class文件被輸入到JVM中進行類文件的加載和執(zhí)行。下面是一個JVM的架構圖。

JVM是如何工作的呢?

正如上面的架構圖所示,JVM被分為三個主要的子系統(tǒng):

類加載器子系統(tǒng)

運行時數(shù)據(jù)區(qū)

執(zhí)行引擎

1. 類加載器子系統(tǒng)

Java的動態(tài)類加載功能是由類加載器子系統(tǒng)處理。當它在運行時(不是編譯時)首次引用一個類時,它加載、鏈接并初始化該類文件。

1.1 加載

類由此組件加載。啟動類加載器 (Boot Strap class Loader)、擴展類加載器(Extension class Loader)和應用程序類加載器(Application class Loader) 這三種類加載器幫助完成類的加載。

啟動類加載器 – 負責從啟動類路徑中加載類,無非就是rt.jar。這個加載器會被賦予最高優(yōu)先級。

擴展類加載器 – 負責加載ext 目錄(jre\lib)內的類.

應用程序類加載器 – 負責加載應用程序級別類路徑,涉及到路徑的環(huán)境變量等etc.

上述的類加載器會遵循委托層次算法(Delegation Hierarchy Algorithm)加載類文件。

1.2 鏈接

校驗 – 字節(jié)碼校驗器會校驗生成的字節(jié)碼是否正確,如果校驗失敗,我們會得到校驗錯誤。

準備 – 分配內存并初始化默認值給所有的靜態(tài)變量。

解析 – 所有符號內存引用被方法區(qū)(Method Area)的原始引用所替代。

1.3 初始化

這是類加載的最后階段,這里所有的靜態(tài)變量會被賦初始值, 并且靜態(tài)塊將被執(zhí)行。

2. 運行時數(shù)據(jù)區(qū)(Runtime Data Area)

運行時數(shù)據(jù)區(qū)域被劃分為5個主要組件:

方法區(qū)(Method Area)?– 所有類級別數(shù)據(jù)將被存儲在這里,包括靜態(tài)變量。每個JVM只有一個方法區(qū),它是一個共享的資源。

堆區(qū)(Heap Area)– 所有的對象和它們相應的實例變量以及數(shù)組將被存儲在這里。每個JVM同樣只有一個堆區(qū)。由于方法區(qū)和堆區(qū)的內存由多個線程共享,所以存儲的數(shù)據(jù)不是線程安全的。

棧區(qū)(Stack Area)– 對每個線程會單獨創(chuàng)建一個運行時棧。對每個函數(shù)呼叫會在棧內存生成一個棧幀(Stack Frame)。所有的局部變量將在棧內存中創(chuàng)建。棧區(qū)是線程安全的,因為它不是一個共享資源。棧幀被分為三個子實體:

1.局部變量數(shù)組– 包含多少個與方法相關的局部變量并且相應的值將被存儲在這里。

2.操作數(shù)棧– 如果需要執(zhí)行任何中間操作,操作數(shù)棧作為運行時工作區(qū)去執(zhí)行指令。

3.幀數(shù)據(jù)– 方法的所有符號都保存在這里。在任意異常的情況下,catch塊的信息將會被保存在幀數(shù)據(jù)里面。

4.PC寄存器– 每個線程都有一個單獨的PC寄存器來保存當前執(zhí)行指令的地址,一旦該指令被執(zhí)行,pc寄存器會被更新至下條指令的地址。

5.本地方法棧– 本地方法棧保存本地方法信息。對每一個線程,將創(chuàng)建一個單獨的本地方法棧。

3. 執(zhí)行引擎

分配給運行時數(shù)據(jù)區(qū)的字節(jié)碼將由執(zhí)行引擎執(zhí)行。執(zhí)行引擎讀取字節(jié)碼并逐段執(zhí)行。

解釋器– 解釋器能快速的解釋字節(jié)碼,但執(zhí)行卻很慢。 解釋器的缺點就是,當一個方法被調用多次,每次都需要重新解釋。

JIT 編譯器– JIT編譯器消除了解釋器的缺點。執(zhí)行引擎利用解釋器轉換字節(jié)碼,但如果是重復的代碼則使用JIT編譯器將全部字節(jié)碼編譯成本機代碼。本機代碼將直接用于重復的方法調用,這提高了系統(tǒng)的性能。

1.中間代碼生成器– 生成中間代碼

2.代碼優(yōu)化器– 負責優(yōu)化上面生成的中間代碼

3.目標代碼生成器?– 負責生成機器代碼或本機代碼

4.探測器(Profiler)?– 一個特殊的組件,負責尋找被多次調用的方法。

3.垃圾回收器: 收集并刪除未引用的對象??梢酝ㄟ^調用"System.gc()"來觸發(fā)垃圾回收,但并不保證會確實進行垃圾回收。JVM的垃圾回收只收集哪些由new關鍵字創(chuàng)建的對象。所以,如果不是用new創(chuàng)建的對象,你可以使用finalize函數(shù)來執(zhí)行清理。

如何才能成為一個公司的頂梁柱般架構師呢?

基本知識

1.學會分析源碼

程序員每天都和代碼打交道。經過數(shù)年的基礎教育和職業(yè)培訓,大部分程序員都會「寫」代碼,或者至少會抄代碼和改代碼。但是,會讀代碼的并不在多數(shù),會讀代碼又真正讀懂一些大項目的源碼的,少之又少。這種怪狀,真要追究起來,怪不得程序員這個群體本身 —— 它是兩個原因造成的:

我們所有的教育和培訓都在強調怎么寫代碼,并沒有教大家如何讀代碼

大多數(shù)工作場景都是一個蘿卜一個坑,我們只需要了解一個系統(tǒng)的局部便能開展工作,讀不相干的代碼,似乎沒用

讀源碼三問:“為什么要有這樣的架構”,“他是什么樣子的”,“他是怎么工作的”。

那么阿里程序員是如何去讀代碼的呢?

2.分布式架構特點及設計理念

首先需要說明的是,分布式系統(tǒng)是一個復雜且寬泛的研究領域,學習一兩門在線課程,看一兩本書可能都是不能完全覆蓋其所有內容的。介于這篇文章是引導初學者入門,所以我個人覺得為初學者介紹一下當前分布式系統(tǒng)領域的全貌,也許比直接推薦論文和課程更有幫助。當初學者對這個領域建立起一個大的 Picture 之后,可以根據(jù)自己的興趣,有選擇性的深入不同領域進行進一步的學習。

3.為什么微服務會這么火?

要學習微服務,首先,我們要了解為什么使用微服務。

代碼難以理解?

構建和部署耗時長,難以定位問題,開發(fā)效率低?

單體只能按整體橫向擴展,無法分模塊垂直擴展?

一個bug有可能引起整個應用的崩潰?

受技術棧限制,團隊成員使用同一框架和語言?

那么如何解決單體的不足呢,通過遷移到微服務架構來解決,我們看一下什么是微服務。

微服務架構:將單體應用拆分為多個高內聚低耦合的小型服務,每個小服務運行在獨立進程,由不同的團隊開發(fā)和維護,服務間采用輕量級通信機制,獨立自動部署,可以采用不同的語言及存儲。

單體架構整個團隊維護開發(fā)一個大工程及一個單庫,到了微服務架構,用戶請求經過API Gateway被路由到下游服務,服務之間以輕量級通信協(xié)議進行通信,服務通過注冊中心發(fā)現(xiàn)彼此,每個服務都有專門的開發(fā)維護團隊,每個服務對應獨立的數(shù)據(jù)庫,服務獨立開發(fā),獨立部署和上線。

接下來我們總結下微服務的優(yōu)點。

易于開發(fā)與維護

微服務相對小,易于理解

啟動時間短,開發(fā)效率高

獨立部署

一個微服務的修改不需要協(xié)調其它服務

伸縮性強

每個服務都可以在橫向和縱向上擴展

每個服務都可按硬件資源的需求進行獨立擴容

與組織結構相匹配

微服務架構可以更好將架構和組織相匹配

每個團隊獨立負責某些服務,獲得更高的生產力

技術異構性

使用最適合該服務的技術

降低嘗試新技術的成本

下面就送上學習架構圖吧

如果你覺得想提升下自己,學習文章中的知識,在此推薦一個免費公開課的地方,可以加群:433540541,找群主獲取上課資格,這是免費的課程,找群主要的時候可以客氣一點。

4.程序員到底要不要學習JVM

總有人問這個東西好像用不上,于是要不要學這樣的問題。

然后又總有人擔心一直搬磚成天做些重復沒提升的東西。

如果你這輩子只甘心做一個平庸的Java碼農,那么你完全沒有必要去學習JVM相關的知識,學習JVM對于一個Java程序員的好處大概可以概括為下幾點:

1.你能夠明白為什么Java最早期被稱為解釋型語言,而后來為什么又被大家叫做解釋與編譯并存的語言(了解JVM中解釋器以及即時編譯器就可以回答這個問題);

2.你能夠理解動態(tài)編譯與靜態(tài)編譯的區(qū)別,以及動態(tài)編譯相對于靜態(tài)編譯到底有什么好處(JVM JIT);

3.你能夠利用一些工具,jmap, jvisualvm, jstat, jconsole等工具可以輔助你觀察Java應用在運行時堆的布局情況,由此你可以通過調整JVM相關參數(shù)提高Java應用的性能;

4.可以清楚知道Java程序是如何執(zhí)行的;

5.可以明白為什么Java等高級語言具有可移植性強的特性。

其實這個問題相當于“為什么C/C++程序員需要學體系結構與編譯原理?”

話不多說,附上學習體系圖

5.被我們忽略掉的工程化專題

IT產業(yè)行業(yè)細分化已經不是一天兩天的事了。集成技術這件事并不可恥可笑,反而是另一種可貴的能力。并不是像一些人形容的那樣,好像批發(fā)幾個CPU,拿到華強北就能把自己的電腦改裝成超級計算機了。

那么,為什么我們常常會忽略掉工程化這件事的價值呢?主要的原因,或許是因為工程化這件事本身就離我們太遠。一個產業(yè)工程化的普遍性越高,說明這個產業(yè)發(fā)展的越成熟:產業(yè)鏈細分、分工細化、全球化的研發(fā)和生產這些高效的工作方式開始出現(xiàn)。而產業(yè)成熟也往往代表著寡頭化情況顯著。

在IT產業(yè)中,寡頭化出現(xiàn)代表著創(chuàng)業(yè)公司減少——沒人再去用聲勢浩大的發(fā)布會講故事、沒人再去宣傳自己拿了多少融資。

這一代中國人自小的教育不比歐美的STEAM,而是重學術、輕手藝。我們往往會為工科和產能過剩畫上等號。強大的資本和技術門檻為這些產業(yè)蒙上了一層神秘的面紗,讓普通人很難真正了解到其中技術和工藝的復雜程度,也就更難明白其中的價值??烧且驗橹袊墓こ袒芰Γ抛屛覀冇袡C會走到AI時代的第一梯隊,而不僅僅是靠學術研究能力。

另外一個原因,或許在于我們天生“叛逆心”。超級計算機、手機芯片等等技術門檻較高的產業(yè),其背后往往是大企業(yè)和國資科研機構。當評判的對象是他們時,我們似乎更愿意相信狗血的商業(yè)故事和陰謀論:比如科研經費都被教授們吃吃喝喝啦;搞超級計算機就是放衛(wèi)星其實美日根本不care啦;XX企業(yè)的技術都是從創(chuàng)業(yè)公司買來的除了會賺用戶的錢啥技術都沒有……

產生這種“叛逆心”的原因太深刻,我們能做到的,只有在這種“慣性思維”出現(xiàn)時先按住自己奔向鍵盤的手,轉表達欲為好奇心,完成自己了解的義務,再去行使自己批判的權利。

附上思維腦圖

6.沒有高并發(fā)經驗,想進大公司該怎么辦?

假如沒有靠譜的公司,接觸不到高并發(fā)的業(yè)務場景怎么辦?你永遠解決的是小問題,工作10年技術也未必提升多少。

很多程序員也經常找我說,沒有經驗就沒有靠譜的公司收,沒有靠譜的公司也就沒有經驗,我看了無數(shù)的書,自己做了無數(shù)的實驗拼命想找個靠譜公司去深入,但是感覺好難,簡直是個死循環(huán)

讀者群的朋友大家都比較關注高并發(fā),原因很簡單,想去BAT這樣的大公司,你必須要有高并發(fā)的經驗。今天普及下高并發(fā)的知識,希望大家對高并發(fā)有一個正確的認識。

7.學習千遍,不如項目實戰(zhàn)成功一次

我們在學習過程中最容易犯的一個錯誤就是:看的多,動手的少。特別是對一些項目的整體開發(fā),我們接觸的機會就更少了。

一次完整的開發(fā),是最好的學習。它能讓你對整個開發(fā)流程有完整的認識,對知識也會有極大的鞏固。更重要的是,你將學會將理論知識用到實際開發(fā)中的方法。

所以無論項目大小,一定要動手去進行開發(fā)學習。

項目實戰(zhàn)相信很多程序員都多少會有的,可是我們這個還要學習什么呢?

那就要看你想不想成為一個架構師了,為什么98%的程序員工作10年,一輩子還只是一個開發(fā)者。程序員們都要想一想這個問題,我是不是需要提升了。

我認為,學習項目實戰(zhàn)最重要的還是學習項目管理,作為程序員,都應該學點項目管理。

凡事皆為“項目”

項目的兩類屬性(復雜的邏輯,龐大的信息量)

人腦擅長的是思考,而不是記憶

成為一個“獨當一面”的人

獨當一面是一個很性感的詞。是否擁有它,對應的職場價值,有著天壤之別的。

所有老板都喜歡“獨當一面”的員工,因為這是最省心力、最好算賬的模式:給你一塊資源,給你一個 title,給你一個目標,然后你給我打出一片天地來。

當你能獨立對一攤子事情負責,并把它們一一搞定,你會擁有大幅度的職場溢價——相應的,其收入回報,也遠非“技術螺絲”可比了。

如果你很進取,你會逐漸地:主導一個小組,一個部門,一個家庭,甚至還是城市……而這所有的一切起點,正是獨立完整地做好一個項目:你沒有誰可以依靠,你要對其中大大小小的事務負責,你要對最后的結果。

換句話說,“項目管理”是“獨當一面”的元能力。在這個過程中,你的意識越發(fā)清晰,你的方法論越發(fā)成熟,你的信心更加沛,項目越做越大。直到某天,你真的有了掌控一方的封疆大吏。

這就是我們學習“項目實戰(zhàn)”的終極意義。

或許作為程序員的你想提升自己,卻找不到突破口,公司沒人帶。又或許你已經工作6年了,卻還是很迷茫,很多知識都還是不懂,也沒有達到自己期望的一個職位,薪資。在此推薦一個免費公開課的地方,上面所提到的架構師基本知識點都有資料,可以加群:617434785,找群主獲取上課資格,這是免費的課程,找群主要的時候可以客氣一點。

到這里,你可能認為文章已經完了,學完這些就可以去BAT大公司做一個架構師,年薪50W+嗎?

不,你錯了,這些都知識最基本的知識,想要成為一個架構師必須是一個累積的過程,也是這么多程序員終其一生也只是一個開發(fā),到年齡就會被公司辭退。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容