高頻面試題-請聊一下JVM的內存結構!

這是我參與更文挑戰的第11天,活動詳情查看: 更文挑戰面試

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

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

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

萬里長征走出第一步。數據結構

今天咱們就來看一下JVM的內存結構,雖然是概念性的知識;但憑藉着理論知識,結合平常的開發工做,日積月累下來,對平時的編程影響甚廣。post

我這裏是以JDK8爲例,描述一下JVM的內存結構,若是想要了解更多更全面的知識,其實買本書看會更有效果,《深刻理解Java虛擬機》。性能

畫了一張圖,先看一下!spa

1.png

總體來講,能夠分爲線程私有、線程共享兩種類型,下面來看一下吧!線程

線程私有

程序計數器(Program Counter Register)

線程執行的字節碼行號指示器,經過改變計數器的值來選取下一條要執行的字節碼指令,只爲Java方法計數。code

由於每一個線程有本身獨立的行號,因爲程序計數器所佔內存小之又小,因此每一個線程使用獨立計數器來處理是說得通的,這樣並不會形成什麼壓力,反而由於每一個線程都私有一個計數器而快不少。

這也就是程序技術器是線程私有的緣由。

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

Java方法執行時的內存模型,包含着諸多個棧幀。

棧幀是方法運行期間中的基礎數據結構,每一個棧幀中主要包含了局部變量、操做數棧、動態鏈接、返回地址等等。

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

這裏還有一個比較重要,並且問的比較頻繁的一個知識點:如何引發StackOverflowError、OutOfMemoryError異常,爲何?

這個問題咱們在以後的文章中會加以講解,你們也能夠自行去研究一下。

本地方法棧

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

線程共享

元空間(MetaSpace)

用於存儲被加載的類信息、常量、靜態變量等等數據。

在JDK1.8以前,這些數據存儲於方法區,也就是咱們常說的永久代(PermGen)。

不一樣於永久代佔用Java虛擬機內存,元空間是直接使用本地內存存儲。

更換成元空間的好處不少,好比:

  1. 字符串常量池存放在永久代中的時候,容易出現內存溢出、性能問題。

  2. 類信息的大小難以肯定,由於永久代使用的是Java虛擬機內存,因此指定永久代內存時會有必定的難度。

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

堆 (Heap)

Java堆是全部線程共享的一塊內存區域,也是Java虛擬機中所管理的最大的一塊內存。

其中存儲着幾乎全部的對象實例,同時咱們以後要說的垃圾回收機制,也是針對堆來講的,由於堆是垃圾收集器管理的主要區域。

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

這個我會在以後垃圾回收的文章裏面仔細說一下,你們也能夠自行查閱書籍。

相關文章
相關標籤/搜索