JVM筆記----Java虛擬機器內部結構介紹
Java與c++之間有一堵由記憶體動態分配和垃圾收集技術所圍成的“高牆”,牆外的人想進去,牆裡面的人卻想出來。
—— 《深入理解Java虛擬機器》 周志明
對於c++來說 , 在記憶體管理領域,他們既是游泳最高權利的皇帝,又是從事最基礎工作的勞動人民。他們擁有每一個物件的
所有權,又揹負著維護每一個物件的責任。
而對於Java程式設計師來說,在JVM的幫助下,不再需要為每一個new 操作去寫配對的delete / free 程式碼,不容易出現記憶體洩漏
和記憶體溢位的問題。
那麼就然我們來一探JVM的底層結構吧~
上圖就是JVM的結構啦~ 那麼下面就讓我來 一 一 介紹 每塊區域的職責和特點
當我們把java程式寫出來的時候,首先要對它進行編譯才可以執行,比如上圖的Math類,我們要首先用javac指令
把它編譯生成位元組碼檔案( .class ) , 然後就可以運行了,而執行時的記憶體管理就依賴於JVM,由JVM對我們的記憶體
進行管理。
程式計數器:
想必學過計算機組成原理的同學對程式計數器都不陌生吧~ 它負責記錄我們的程式碼執行到哪一行,以及負責一些流程控制。
位元組碼直譯器工作時會通過改變計數器的值來選去下一條指令,分支,迴圈,跳轉,異常處理,執行緒恢復都需要計數器。
每條執行緒都需要一個獨立計數器,各執行緒計數器互不影響,這類記憶體區域稱為“執行緒私有”記憶體。
棧(執行緒):
執行緒私有,生命週期與執行緒相同。
每個方法在執行的時候會建立一個棧幀用於儲存 區域性變量表 、 運算元棧 、 動態連結 、 方法出口
每一個方法從呼叫直到執行完成的過程,就對應一個棧幀在虛擬機器中入棧到出棧的過程。
區域性變量表:存放各種基本資料型別 ( boolean , byte , char , short , int , float , long , double ) 沒有 String!
物件引用 ( 指向物件起始地址的指標 )
return Address 型別 (指向一條位元組碼指令的地址)
它有哪些異常呢? 有:執行緒請求的棧深度大於JVM所允許,StackOverflowError
若棧可以動態擴充套件,無發申請到足夠記憶體時,OutOfMemoryError
本地方法棧:
與虛擬機器棧區別:虛擬機器棧為JVM執行Java方法服務
方法棧為JVM使用到的Native方法服務
也會丟擲StackOverflowError, OutOfMemoryError
堆:
記憶體最大 被所有執行緒共享
幾乎所有的物件例項和陣列都要在堆中分配記憶體(除了靜態等)
若在堆中沒有記憶體完成例項分配,且堆無法擴充套件時,丟擲OutOfMemoryError
方法區:
各執行緒共享
用於儲存類資訊,常量,靜態變數,編譯後的程式碼
垃圾收集很少出現
執行時常量池:
方法區的一部分
存放編譯期生成的各種字面量和符號引號(常量池)
這部分內容在類載入後進入方法區的執行時常量池中存放
直接記憶體:
不是JVM執行時資料區的一部分,也不是JVM規範中定義的記憶體區域
那麼今天的JVM就介紹到這裡~
下一次我會介紹JVM是如何建立物件的哦~