深入淺出JVM之知識體系(一)
一.JVM知識體系組成
1.JVM記憶體區域
(1)組成部分
(2)各部分的作用
2.JVM記憶體溢位
(1)記憶體溢位
(2)棧溢位
(3)記憶體區域與溢位的關聯
3.垃圾回收機制
(1)物件存活狀態判斷
(2)垃圾收集演算法
(3)垃圾收集器
(4)垃圾回收過程
4.類載入
(1)類的生命週期
(2)類載入器
5.效能調優
(1)常見問題
(2)解決方案
(3)調優工具
(4)調優參考資料
二.JVM知識相關基礎
1.JVM記憶體區域(組成部分及其作用)
(1)執行緒共享部分
a.Java堆
JVM管理記憶體中最大的一塊;主要存放物件例項以及陣列
b.方法區
儲存已被虛擬機器載入的類資訊、常量、靜態變數以及即時編譯器編譯後的程式碼等資料
(2)執行緒私有部分
c.虛擬機器棧
執行緒私有,生命週期與執行緒一致,即執行緒活虛擬機器棧活,執行緒亡虛擬機器棧亡;與Java方法過程相關,即java方法的進入與退出,代表著棧幀的進棧與出棧;棧幀主要儲存區域性變量表、運算元棧、動態連結、出口資訊等
d.本地方法棧
與虛擬機器棧類似,主要區別在於,本地方法棧與native方法相關
e.程式計數器
記憶體空間小;如果執行緒執行的為java方法,則儲存的為正在執行虛擬機器位元組碼指令的地址,如果為Native方法,則為undefined;分支、迴圈、調整,異常處理、執行緒恢復等處理都依賴於程式計數器
2.JVM記憶體溢位
(1)程式計數器
此部分是唯一一個在JVM規範裡沒有定義OutOfMemoryError異常的區域
(2)虛擬機器棧
StackOverflowError:當執行緒請求的棧超出了虛擬機器的深度;
OutOfMemoryError:如果虛擬機器可以動態擴充套件,當擴充套件時無法申請足夠的記憶體
(3)本地方法棧
類似虛擬機器棧
(4)Java堆
OutOfMemoryError:當堆中沒有記憶體完成例項分配並且也無法拓展時
(5)方法區
OutOfMemoryError:執行時常量池為方法區中的一部分,儲存的是字面量和符號引用,記憶體有限當無法申請時
3.垃圾回收機制
(1)物件存活狀態判斷
a.引用計數器,但是無法解決迴圈引用的問題;
b.可達性分析法。如果到GC Roots存在路徑即引用鏈則為可活物件,若沒有則認為該物件為不可用
補充知識:
a.四種引用
b.finalize()方法
(2)垃圾收集演算法(回收理論)
a.標記-清除演算法
效率低;會產生大量不連續的記憶體碎片
b.複製演算法(新生代)
存活率高時,複製效率較低
c.標記-整理演算法(老生代)
先進行標記清除,讓所有的存活物件往一端移動,最後清除邊界以為的記憶體
(3)垃圾收集器(回收實踐)
新生代:
a.Serial
單執行緒
b.Partnew
多執行緒並行
c.Parallel Scavenge
多執行緒並行
老生代:
a.CMS
最短回收停頓時間,標記清除
b.Serial Old
單執行緒,標記整理
c.Parallel Old
多執行緒,標記整理
(4)垃圾回收過程
判斷物件是否死亡->運用垃圾回收演算法進行回收
4.類載入
(1)類的生命週期
a.載入
先根據一個類的全限定類名來獲取到它的二進位制位元組流->再將此二進位制位元組流代表的靜態儲存結構轉換為方法區的執行時資料結構->最後在記憶體中生成該類對應的java.lang.class物件,作為方法區的該類各種資料的訪問入口
b.連線
驗證:進行檔案格式、元資料、位元組碼以及符號引用等驗證
準備:為類變數分配記憶體並設定初始值
解析:將符號引用轉化為直接引用
c.初始化
呼叫初始化方法,進行初始化類變數、靜態程式碼塊等
d.使用
e.解除安裝
(2)類載入器
a.啟動類載入器(c++實現,為虛擬機器的一部分)
載入 lib 下或被 -Xbootclasspath 路徑下的類
b.擴充套件類載入器
載入 lib/ext 或者被 java.ext.dirs 系統變數所指定的路徑下的類
c.應用程式類載入器
ClassLoader負責,載入使用者路徑上所指定的類庫。
d.自定義類載入器
補充:
雙親委派模型:指當一個類載入器收到一個類載入的請求時,首先它自己不會主動去載入,而是通知它的父類去載入,當父類無法完成時子類才會嘗試去載入
5.效能調優(此部分待補充)