JVM性能調優—Java內存的基礎知識


本文將全面介紹Java內存區域劃分的知識,這是JVM性能調優的基礎知識,只有掌握了Java虛擬機的基礎知識,才能對JVM性能調優得心應手,否則只能遭遇"摸著石頭過河"的技術困境。 如圖

Figure-1描述了JVM內存區域劃分的模塊,分別有程序計數器、Java虛擬機棧、本地方法棧、方法區和Java堆五部分組成。

JVM性能調優—Java內存的基礎知識

Java內存區域劃分圖:Figure-1


為了能夠把JVM這部分知識梳理清楚,我將從如下方面講解:

一、程序計數器它是JVM劃分的一塊內存空間,為了保存當前正在執行的線程字節碼行號,這塊內存空間在JVM中是最小的一塊,相比其它內存區域,甚至可以忽略這塊的大小。

JVM性能調優—Java內存的基礎知識

程序計數器執行圖:Figure-2


如上圖Figure-2表達了程序計數器的工作過程,當JVM執行引擎解釋執行字節代碼時,每執行一行,首先會把當前執行的字節碼行號保存到程序計數器中。那麼,或許您會問到:"為什麼要記錄那個行號幹啥呢?",大家都知道Java語言執行都是以多線程為單位進行執行的,並且每個線程都有著自己的優先級;線程執行過程可能會發生搶佔式的中斷(暫停),這是在多線程語言環境中最容易發生的常見問題,講到這裡再回答上面的問題就容易了,恢復中斷的線程是通過程序計數器中記錄的行號,JVM引擎通過那個線程的字節碼行號繼續往下執行。每個線程執行時都會創建一個獨立的程序計數器,這樣才能保證線程之間執行不會受到影響。

二、Java虛擬機棧,它是描述方法執行的內存模型,即方法代碼執行過程的內存。線程的方法執行時都會創建一個棧幀(數據結構),棧幀是描述這個方法執行的動態數據狀態,它包括局部變量表、操作數棧、動態鏈接、方法返回地址等等。一個方法的執行對於JVM虛擬機來說,就是一個進棧與出棧的過程。

JVM性能調優—Java內存的基礎知識

棧幀圖:Figure-3

三、本地方法棧,是為了執行本地Native方法時劃分出的一塊內存空間,它描述的是執行本地方法Native的過程,而相對於Java虛擬棧則是描述JVM執行字節碼的過程。本地方法棧主要用於調用C/C++語言的動態鏈接庫dll(類似於jar包)而服務的。

JVM性能調優—Java內存的基礎知識

本地方法棧 Figure-4

四、方法區, 它存儲來自Java虛擬機加載的class字節碼文件,把這個文件轉儲到內存信息分別有類信息、接口、父類、方法等;運行時常量池也屬於方法區中的存儲信息,主要包括類中的屬性常量、靜態常量等。

JVM性能調優—Java內存的基礎知識

方法區圖 Figure-5

五、Java棧,主要用於存放實例對象的內存空間,它是JVM內存空間佔比最大的一塊。所有涉及到new指令實例化的對象都存儲在棧內存空間中,因此,這一塊也正是GC垃圾回收佔比最大的區域。

JVM性能調優—Java內存的基礎知識

Java堆圖 Figure-6


如上圖所示,Java堆內存空間可以分為新生代(Young Generation)和老年代(Old Generation);同時新生代又劃分為Eden、S0和S1區,這塊內容的視頻講解已發佈到頭條,感興趣的可以找一下我的頭條空間。

綜上所述,JVM內存區域的劃分充分體現了JVM虛擬機技術採用了模塊化的方法,每個區域的定義都有清晰的職責範圍和互相聯繫。只有搞清楚了JVM內存區域劃分的規則和內涵,才能算是對Java虛擬機內存區域有所瞭解和認識。


分享到:


相關文章: