【淺談JVM】之記憶體模型
java虛擬機器在執行java程式的過程中會把它所管理的記憶體劃分為若干個不同的資料區域。每個區域有自己建立和銷燬時間,根據《java虛擬機器規範》的規定,java虛擬機器所管理的記憶體將會包括以下幾個執行時資料區域,如下:
1,程式計數器 程式計數器是一塊較小的記憶體空間,它當前執行緒所執行的位元組碼的行號指示器,在虛擬機器的概念模型裡,位元組碼解釋工作就是通過改變這個計數器的值來選取下一條需要執行的位元組碼指令,分支、迴圈、跳轉、異常處理執行緒回覆等基礎功能都需要依賴這個計數器來完成。 java虛擬的多執行緒是通過執行緒輪流切換並分配處理器執行時間的方式實現的,在任何一個確定的時刻,一個處理器指揮執行一條執行緒的指令。因此它是執行緒私有的記憶體空間
2,java虛擬機器棧 和程式計數器一樣,它也是執行緒私有的,它的生命週期和執行緒相同。虛擬機器描述的是java方法執行的記憶體模型:每個方法在執行的時候都會建立一個棧幀用於區域性變量表、運算元棧、動態連結、方法出口等資訊。每一個方法的執行過程,對應著一個棧幀在虛擬機器棧中的出棧入棧的過程。 區域性變量表存放了編譯可知的各種基本資料型別、物件引用(可能是一個物件起始地址的引用指標,也可能是指向一個代表物件的控制代碼)和returnAddress型別()指向一條位元組碼指令的地址
3,本地方法棧 與虛擬機器棧所發揮的作用相似,區別是執行的是native方法
4,java堆 java堆是java虛擬機器管理的記憶體中最大的一塊。java堆是被所有執行緒共享的一塊記憶體區域,在虛擬機器啟動是建立。此記憶體區域的唯一目的就是存放物件例項,它是垃圾收集器管理的主要區域,可細分為年輕代和老年代,新生代又被分為1個Eden空間和2個survivor空間(預設比例8:1:1-XX:SurvivorRatio=8),java堆一般是可擴充套件的由jvm引數控制:-Xms20m設定堆最小記憶體,-Xmx40控制最大記憶體,-Xmn10m設定年輕代記憶體大小。java1.7開始字串常量池移入堆中
5,元資料空間 元資料空間是和直接記憶體一樣,屬於java管理的記憶體外的一塊記憶體空間,用於儲存虛擬機器載入的類資訊,即使編譯器編譯後的程式碼等資料。替代了JAVA1.7以前的方法區的功能,而方法區存放的常量,靜態變數被移至java堆中存放
6,執行時常量池 執行時常量池用於存放編譯器生成的各種字面量(Literal)和符號引用(Symbolic References),每個類都有一個常量池 字面量包括:1.文字字串 2.八種基本型別的值 3.被宣告為final的常量等; 符號引用包括:1.類和方法的全限定名 2.欄位的名稱和描述符 3.方法的名稱和描述符。 在類載入解析的過程會去查詢字串常量池,以保證執行時常量池所引用的字串與字串常量池中是一致的。 注:區別於字串常量池(jvm中只有一個)
7,直接記憶體 在java1.4中新加入了NIO(New Input/Output)類,引入了一種基於通道和緩衝區的I/O方式,它可以使用Native函式庫直接分配堆外記憶體,然後通過一個儲存在java對重的DirectByteBuffer物件作為這塊記憶體的引用進行操作。
參考資料:深入理解java虛擬機器-周志明著