文章內容輸出來源:拉勾教育Java高薪訓練營,做者:孫裏java
前言
對於面試中涉及的一些問題,大可能是層次多,知識點雜,不方便記憶,常常是一聽就會,一面就忘。 我想到了一個對本身頗有效的記憶方法:類比聯想記憶法。面試
其實這個方法你們很熟悉,也很經常使用,只是須要找到比較貼切且適合本身的事物進行關聯。 特此分享一下本身的經驗。本文目的不在於知識的講解,而在於知識的持久化。若有錯誤,歡迎指正。數組
不知道你們以前對jvm的內存結構能記住多少,認真看完之後嘗試每天回憶下這個場景。 由於除了第一次創建記憶鏈接之外,還須要常常在腦中反覆強化這個鏈接,才能達到深入記憶的效果。數據結構
先總體瀏覽下JVM內存結構:大致上分爲三個層次,二十多個知識點。
第一層
概念
-
類加載器:做用是將java 文件通過編譯後會獲得 .class 文件加載到內存。jvm
-
本地庫接口:用native修飾的,不能和abstract共同使用的,不顯示方法體但倒是用非Java語言實現方法體的方法。spa
-
運行時數據區:java虛擬機在執行Java程序的過程當中會把它管理的內存分爲若干個不一樣的數據區域。操作系統
-
執行引擎:jvm核心組成部分之一,創建在處理器、硬件和操做系統層面之上。引擎在執行代碼時會有解釋執行和編譯執行兩種選擇,輸入字節碼文件,解析字節碼輸出結果。線程
類比
回顧完基本概念後,咱們再關聯上一個更加容易記憶的場景,左側爲類比事物,右側爲對應知識點。對象
想象一下一輛剛剛駛入加油站的汽車:blog
-
司機拿起加油槍(類加載器)
-
對準加油口(本地庫接口)開始加油(開始類加載的過程,後邊會再分析)
-
加油的目的是供給發動機可使用的燃料(執行引擎)
-
而後纔可讓車繼續保持行駛狀態(運行時數據區)
第二層:類加載器
概念
-
加載:指的是將類的class文件讀入到內存,併爲之建立一個java.lang.Class對象。
-
連接:當類被加載以後,系統爲之生成一個對應的Class對象,接着將會進入連接階段,鏈接階段負責把類的二進制數據合併到JRE中。類鏈接又可分爲以下3個階段。
-
驗證:用於檢驗被加載的類是否有正確的內部結構,並和其餘類協調一致。
-
準備:負責爲類的靜態變量分配內存,並設置默認初始值。
-
解析:將類的二進制數據中的符號引用替換成直接引用。
-
-
初始化:爲類的靜態變量賦予正確的初始值。
-
使用:業務處理中被引用。
-
銷燬:再也不使用時被垃圾回收。
類比
再來類比下汽油使用的整個過程:
-
加載:將汽油添加到油箱。
-
連接:讓發動機的油路中充滿汽油。
-
驗證:檢查汽油是否符合發動機要求。
-
準備:汽油和發動機已完成啓動前的準備狀態。
-
解析:汽油開始燃燒併產出動力,化學燃料轉換成物理的作功。
-
-
初始化:發動機啓動完畢。
-
使用:汽車行駛過程當中,發動機使用汽油持續運轉。
-
銷燬:汽油被消耗。
第二層:運行時數據區
概念
-
程序計數器:記錄的是正在執行的虛擬機字節碼指令的地址。
-
虛擬機棧:Java 方法執行的內存模型。
-
本地方法棧:區別於Java 虛擬機棧的是,Java 虛擬機棧爲虛擬機執行 Java 方法(也就是字節碼)服務,而本地方法棧則爲虛擬機使用到的Native 方法服務。
-
堆:這塊區域是 JVM 所管理的內存中最大的一塊。線程共享,主要是存放對象實例和數組。
-
方法區:屬於共享內存區域,存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。
類比
-
程序計數器:記錄汽車行駛距離的里程錶。
-
虛擬機棧:電動車電池。
-
本地方法棧:汽油車油箱。
-
堆:能夠堆放大件貨物的後備箱。
-
方法區:能夠提供操做汽車的各類方法的駕駛區域。
第三層:虛擬機棧
概念
棧幀( Frame)是用來存儲數據和部分過程結果的數據結構,同時也被用來處理動態連接 (Dynamic Linking)、 方法返回值和異常分派( Dispatch Exception)。棧幀隨着方法調用而建立,隨着方法結束而銷燬——不管方法是正常完成仍是異常完成(拋出了在方法內未被捕獲的異常)都算做方法結束。
-
局部變量表:一組變量值存儲空間,用於存放方法參數和方法內部定義的局部變量。
-
操做數棧:一個後進先出棧,其最大深度在編譯的時候已經肯定了。當一個方法剛剛開始執行的時候,這個方法的操做數佔是空的,在方法的執行過程當中,會有各類字節碼指令往操做數佔中寫入和提取內容,這就是出棧/入棧動做。
-
動態連接:每個棧幀都包含一個執行運行時常量池中該棧幀所屬方法的引用。持有這個引用是爲了支持方法調用過程當中的動態鏈接。
-
返回出口:方法正常退出,將會返回程序結束其的值給上層方法,通過調整以後以指向方法調用指令後面的一條指令,繼續執行上層方法。
-
正常完成出口:方法正確執行,執行引擎遇到方法返回的指令,回到上層的方法調用者。
-
異常完成出口:方法執行過程當中發生異常,而且沒有處理異常,這樣是不會給上層調用者產生任何返回值。
-
類比
每個方法從調用直至執行完成的過程,就對應着一個棧幀在虛擬機棧中入棧到出棧的過程。對應着每一次快遞派送:
-
局部變量表:每次派送的貨物清單。
-
操做數棧:貨車的貨箱,只能棧式搬運貨物。
-
動態連接:實時動態規劃路徑。
-
返回出口:到達終點之後就能夠返回了。
總結
最後,咱們再回顧下整個思路,方便平時反覆回憶。
-
貨車進入加油站進行加油時需用加油槍(類加載器)對準了加油口(本地庫接口)。加過油的車可讓發動機(執行引擎)運轉起來,並保持行駛狀態(運行時數據區)。
-
加油過程當中,汽油從油槍進入了油箱(加載),並抵達了發動機(連接)。這個過程當中車載電腦檢查了汽油(驗證),並使汽油和發動機都進入啓動前的準備狀態(準備)。而後汽油開始燃燒,轉化爲動力勢能(解析),發動機啓動完成後(初始化)開始使用汽油(使用),當汽油燃燒後就被消耗了(銷燬)。
-
因此駕駛員坐在能夠操做汽車的駕駛室(方法區)操縱貨箱(堆)載滿貨物的貨車時,會觀察記錄移動距離的里程錶和油箱指示燈(程序計數器),判斷何時須要再次加油。而油電混合的汽車也會藉助油箱(本地方法棧)的汽油燃燒給電池充電(虛擬機棧)。
-
貨車的目的是將貨箱(操做數棧)的貨物(局部變量)運送到目的地(返回出口),途中會藉助導航地圖實時調整路線(動態連接)。