首頁歷史 > 正文

高頻面試題-請聊一下JVM的記憶體結構

2022-01-06由 Ijiran的程式設計思維 發表于 歷史

凡是三年以上開發經驗的人,都會在簡歷上寫上這麼一句話,瞭解/熟悉JVM(記憶體結構),對垃圾回收機制有一定的理解。

但是往往大部分人是一問三不知的,或者是沒準備充分,又或者是根本就是瞎編,最起碼背一下概念,說不準面試官也不會呢。

接下來的文章會圍繞著JVM、JMM、垃圾回收演算法、垃圾回收器、如何調優幾個方面的知識來聊一下。

萬里長征走出第一步。

今天我們就來看一下JVM的記憶體結構,雖然是概念性的知識;但憑藉著理論知識,結合日常的開發工作,日積月累下來,對平時的程式設計影響甚廣。

我這裡是以JDK8為例,描述一下JVM的記憶體結構,如果想要了解更多更全面的知識,其實買本書看會更有效果,《深入理解Java虛擬機器》。

畫了一張圖,先看一下!

高頻面試題-請聊一下JVM的記憶體結構

整體來說,可以分為執行緒私有、執行緒共享兩種型別,下面來看一下吧!

執行緒私有

程式計數器(Program Counter Register)

執行緒執行的位元組碼行號指示器,透過改變計數器的值來選取下一條要執行的位元組碼指令,只為Java方法計數。

因為每個執行緒有自己獨立的行號,由於程式計數器所佔記憶體小之又小,所以每個執行緒使用獨立計數器來處理是說得通的,這樣並不會造成什麼壓力,反而因為每個執行緒都私有一個計數器而快很多。

這也就是程式技術器是執行緒私有的原因。

虛擬機器棧 (Stack)(特性:後進先出)

Java方法執行時的記憶體模型,包含著諸多個棧幀。

棧幀是方法執行期間中的基礎資料結構,每個棧幀中主要包含了區域性變數、運算元棧、動態連線、返回地址等等。

虛擬機器棧中儲存了執行緒中執行方法的棧幀,只有當方法執行完畢後,棧幀才會被銷燬。

這裡還有一個比較重要的,而且問的比較頻繁的一個知識點:如何引起StackOverflowError、OutOfMemoryError異常,為什麼?

這個問題我們在之後的文章中會加以講解,大家也可以自行去研究一下。

本地方法棧

本地方法棧與虛擬機器棧的功能類似,虛擬機器棧是為Java方法提供服務,而本地方法棧是為Native方法服務。

執行緒共享

元空間(MetaSpace)

用於儲存被載入的類資訊、常量、靜態變數等等資料。

在JDK1。8之前,這些資料儲存於方法區,也就是我們常說的永久代(PermGen)。

不同於永久代佔用

Java虛擬機器記憶體

,元空間是直接使用

本地記憶體

儲存。

更換成元空間的好處很多,比如:

字串常量池存放在永久代中的時候,容易出現記憶體溢位、效能問題。

類資訊的大小難以確定,因為永久代使用的是Java虛擬機器記憶體,所以指定永久代記憶體時會有一定的難度。

在《深入理解Java虛擬機器》一書中提到過,其他虛擬機器(如:JRockit、IBM J9)等,都沒有永久代。這也就說明了Java虛擬機器(HotSpot)無法與其他的虛擬機器進行整合搭配;當使用了元空間後,這個問題就迎刃而解了。

堆 (Heap)

Java堆是所有執行緒共享的一塊記憶體區域,也是Java虛擬機器中所管理的最大的一塊記憶體。

其中儲存著幾乎所有的物件例項,同時我們之後要說的垃圾回收機制,也是針對堆來說的,因為堆是垃圾收集器管理的主要區域。

如果根據垃圾回收集器的角度來看,堆還能分為新生代(Eden、From Survivor、To Survivor)、老年代。

這個我會在之後垃圾回收的文章裡面仔細說一下,大家也可以自行查閱書籍。

頂部