1. 程式人生 > >Java效能優化之JVM記憶體模型

Java效能優化之JVM記憶體模型

JVM記憶體模型

首先介紹下Java程式具體執行的過程:

Java原始碼檔案(.java字尾)會被Java編譯器編譯為位元組碼檔案(.class字尾);

由JVM中的類載入器載入各個類的位元組碼檔案,載入完畢之後,交由JVM執行引擎執行

在整個程式執行過程中,JVM會用==一段空間==來儲存程式執行期間需要用到的資料和相關資訊,這段空間一般被稱作為==Runtime Data Area(執行時資料區)==,也就是我們常說的JVM記憶體;

因此,在Java中我們常常說到的記憶體管理就是針對這段空間進行管理(如何分配和回收記憶體空間)

JVM的記憶體劃分和各區域職責

程式計數器:程式計數器是指CPU中的暫存器,它儲存的是==程式當前執行的指令的地址==(也可以說儲存下一條指令的所在儲存單元的地址),當CPU需要執行指令時,需要從程式計數器中得到當前需要執行的指令所在儲存單元的地址,然後根據得到的地址獲取到指令,在得到指令之後,程式計數器便自動加1或者根據轉移指標得到下一條指令的地址,如此迴圈,直至執行完所有的指令;

注:JVM中的程式計數器並不像組合語言中的程式計數器一樣是物理概念上的CPU暫存器,但是邏輯作用上是等同的,在JVM中多執行緒是通過執行緒輪流切換來獲得CPU執行時間的,在任一具體時刻,一個CPU的核心只會執行一條執行緒中的指令,為了能夠使得每個執行緒都線上程切換後能夠恢復在切換之前的程式執行位置,每個執行緒都需要有自己獨立的程式計數器,並且不能互相被幹擾,否則就會影響到程式的正常執行次序。==因此,可以這麼說,程式計數器是每個執行緒所私有的==

Java棧:Java棧是Java方法執行的記憶體模型,Java棧中存放的是一個個的棧幀,每個棧幀(包括:區域性變量表、運算元棧、執行時常量池(在下文中提到的方法區內)的引用、方法返回地址和一些額外的附加資訊)對應一個被呼叫的方法,當執行緒執行一個方法時,就會隨之建立一個對應的棧幀,並將建立的棧幀壓棧。當方法執行完畢之後,便會將棧幀出棧;

注:由於每個執行緒正在執行的方法可能不同,因此每個執行緒都會有一個自己的Java棧,互不干擾

本地方法棧:Java棧是為執行Java方法服務的,而本地方法棧則是為執行本地方法(Native Method)服務的;

堆:Java中的堆是用來儲存物件本身的以及陣列;

方法區:它與堆一樣,是被執行緒共享的區域,儲存了每個類的資訊(包括類的名稱、方法資訊、欄位資訊)、靜態變數、常量以及編譯器編譯後的程式碼等。

注:在方法區中有一個非常重要的部分就是執行時常量池,它是每一個類或介面的常量池的執行時表示形式,在類和介面被載入到JVM後,對應的執行時常量池就被創建出來。當然並非Class檔案常量池中的內容才能進入執行時常量池,在執行期間也可將新的常量放入執行時常量池中,比如String的intern方法。