面試官:今天來聊聊JVM的記憶體結構吧?
候選者:嗯,好的
候選者:前幾次面試的時候也提到了:class檔案會被類載入器裝載至JVM中,並且JVM會負責程式「執行時」的「記憶體管理」
候選者:而JVM的記憶體結構,往往指的就是JVM定義的「執行時資料區域」
候選者:簡單來說就分為了5大塊:方法區、堆、程式計數器、虛擬機器棧、本地方法棧
候選者:要值得注意的是:這是JVM「規範」的分割槽概念,到具體的實現落地,不同的廠商實現可能是有所區別的。
面試官:嗯,順便講下你這圖上每個區域的內容吧。
候選者:好的,那我就先從「程式計數器」開始講起吧。
候選者:Java是多執行緒的語言,我們知道假設執行緒數大於CPU數,就很有可能有「執行緒切換」現象,切換意味著「中斷」和「恢復」,那自然就需要有一塊區域來儲存「當前執行緒的執行資訊」
候選者:所以,程式計數器就是用於記錄各個執行緒執行的位元組碼的地址(分支、迴圈、跳轉、異常、執行緒恢復等都依賴於計數器)
面試官:好的,理解了。
候選者:那接下來我就說下「虛擬機器棧」吧
候選者:每個執行緒在建立的時候都會建立一個「虛擬機器棧」,每次方法呼叫都會建立一個「棧幀」。每個「棧幀」會包含幾塊內容:區域性變數表、運算元棧、動態連線和返回地址
候選者:瞭解了「虛擬機器棧」的組成後,也不難猜出它的作用了:它儲存方法了區域性變數、部分變數的計算並參與了方法的呼叫和返回。
面試官:ok,瞭解了
候選者:下面就說下「本地方法棧」吧
候選者:本地方法棧跟虛擬機器棧的功能類似,虛擬機器棧用於管理 Java 函式的呼叫,而本地方法棧則用於管理本地方法的呼叫。這裡的「本地方法」指的是「非Java方法」,一般本地方法是使用C語言實現的。
面試官:嗯…
候選者:嗯,說完了「本地方法棧」、「虛擬機器棧」和「程式計數器」,哦,下面還有「方法區」和「堆」
候選者:那我先說「方法區」吧
候選者:前面提到了執行時資料區這個「分割槽」是JVM的「規範」,具體的落地實現,不同的虛擬機器廠商可能是不一樣的
候選者:所以「方法區」也只是 JVM 中規範的一部分而已。
候選者:在HotSpot虛擬機器,就會常常提到「永久代」這個詞。HotSpot虛擬機器在「JDK8前」用「永久代」實現了「方法區」,而很多其他廠商的虛擬機器其實是沒有「永久代」的概念的。
候選者:我們下面的內容就都用HotSpot虛擬機器來說明好了。
候選者:在JDK8中,已經用「元空間」來替代了「永久代」作為「方法區」的實現了
面試官:嗯…
候選者:方法區主要是用來存放已被虛擬機器載入的「類相關資訊」:包括類資訊、常量池
候選者:類資訊又包括了類的版本、欄位、方法、介面和父類等資訊。
候選者:常量池又可以分「靜態常量池」和「執行時常量池」
候選者:靜態常量池主要儲存的是「字面量」以及「符號引用」等資訊,靜態常量池也包括了我們說的「字串常量池」。
候選者:「執行時常量池」儲存的是「類載入」時生成的「直接引用」等資訊。
面試官:嗯…
候選者:又值得注意的是:從「邏輯分割槽」的角度而言「常量池」是屬於「方法區」的
候選者:但自從在「JDK7」以後,就已經把「執行時常量池」和「靜態常量池」轉移到了「堆」記憶體中進行儲存(對於「物理分割槽」來說「執行時常量池」和「靜態常量池』就屬於堆)
面試官:嗯,這資訊量有點多
面試官:我想問下,你說從「JDK8」已經把「方法區」的實現從「永久代」變成「元空間」,有什麼區別?
候選者:最主要的區別就是:「元空間」儲存不在虛擬機器中,而是使用本地記憶體,JVM 不會再出現方法區的記憶體溢位,以往「永久代」經常因為記憶體不夠用導致跑出OOM異常。
候選者:按JDK8版本,總結起來其實就相當於:「類資訊」是儲存在「元空間」的(也有人把「類資訊」這塊叫做「類資訊常量池」,主要是叫法不同,意思到位就好)
候選者:而「常量池」用JDK7開始,從「物理儲存」角度上就在「堆中」,這是沒有變化的。
面試官:嗯,我聽懂了
面試官:最後來講講「堆」這塊區域吧
候選者:嗯,「堆」是執行緒共享的區域,幾乎類的例項和陣列分配的記憶體都來自於它
候選者:「堆」被劃分為「新生代」和「老年代」,「新生代」又被進一步劃分為 Eden 和 Survivor 區,最後 Survivor 由 From Survivor 和 To Survivor 組成
候選者:不多BB,我也畫圖吧
候選者:將「堆記憶體」分開了幾塊區域,主要跟「記憶體回收」有關(垃圾回收機制)
面試官:那垃圾回收這塊等下次吧,這個延伸下去又很多東西了
面試官:你要不先講講JVM記憶體結構和Java記憶體模型有啥區別吧?
候選者:他們倆沒有啥直接關聯,其實兩次面試過後,應該你就有感覺了
候選者:Java記憶體模型是跟「併發」相關的,它是為了遮蔽底層細節而提出的規範,希望在上層(Java層面上)在操作記憶體時在不同的平臺上也有相同的效果
候選者:Java記憶體結構(又稱為執行時資料區域),它描述著當我們的class檔案載入至虛擬機器後,各個分割槽的「邏輯結構」是如何的,每個分割槽承擔著什麼作用。
面試官:瞭解了
今日總結:JVM記憶體結構組成(JVM記憶體結構又稱為「執行時資料區域」。主要有五部分組成:虛擬機器棧、本地方法棧、程式計數器、方法區和堆。其中方法區和堆是執行緒共享的。虛擬機器棧、本地方法棧以及程式計數器是執行緒隔離的)
歡迎關注我的微信公眾號【Java3y】來聊聊Java面試,對線面試官系列持續更新中!
【對線面試官-移動端】系列 一週兩篇持續更新中!
【對線面試官-電腦端】系列 一週兩篇持續更新中!
原創不易!!求三連!!