最近抽空從新溫習一下JVM的概念,如今把心得記錄一下。java
第一部分:根據學習抽象出一個JVM的概念圖,描述各個主要組件的構成和基本做用。數組
第二部分:根據結構圖,對內容進行說明。jvm
1)--JVM的概念
JVM是JAVA VIRTUAL MACHINE的縮寫,它是一個虛擬的計算機設備。
通常的高級語言要想在不一樣的平臺上運行,那麼首先要編譯成平臺識別的編譯語言。
java具備跨平臺性,其中的核心特色就是使用了JVM。
使用了JVM以後,java只須要編譯成JVM中識別的字節碼就能夠了,而後JVM會根據運行平臺,把字節碼轉換爲平臺識別的計算機指令。
一次編譯,處處執行。
2)數據類型
2.1基本數據類型,數據類型及字節數。
1-----------2-----------4-----------8
byte short int long
char float double
上述7種數據類型不須要硬件標記,操做這些數據時字節碼自己已經給出了操做類型,例如:fadd,iadd,dadd
2.2其餘類型
4字節:object類型,盛放對其餘JavaObject的引用。
注意:數組類型會被當作Object類型處理。全部的數據都應該遵照數據類型規則。不然jvm會拒絕執行字節碼。
3)組件
爲了實現跨平臺的特性,JVM設計出組件標準,支撐虛擬的計算機模型。
1.JVM指令系統
2.JVM寄存器
3.JVM棧結構
4.JVM碎片回收堆
5.JVM存儲區-常量池
6.JVM存儲區-方法區
4)原理
JVM是Java的基礎和核心,是JAVA編譯器同操做系統及硬件平臺之間的中間層,是一個抽象的計算機。
java編譯器生成JVM識別的字節碼,JVM根據字節碼生成操做系統的機器碼,在對應的平臺上執行。
對於JAVA的程序來講,JVM是一個程序運行容器,對於操做系統而言JVM是一個進程。
4.1)執行過程--JVM初始化做業
程序執行時,首先調用JAVA.exe(java.exe是一個外殼,其實內部發生核心做用的時JVM.dll)
java_md.c,java.c兩個文件調用jvm.cfg,進行虛擬機的初始化,而且裝載jvm.dll。
jvm.dll掛載JNIEVE(java環境),接下來就開始加載類,進行操做。
4.2)執行過程--類加載
classLoader加載要執行的.class文件
進行字節碼的校驗
申請並管理存儲區域,垃圾回收
使用java解釋器進行解釋,生成機器碼
操做系統執行機器碼
5)指令系統
指令系統是指令的集合,每條指令由操做碼和操做數組成。
操做碼由8位2進制數組成,最大256種,如今已經使用160種以上。
操做數根據實際變化而變化,超過8位時,新增一個字節。
如 iadd,iand等都是操做碼。
6)寄存器
分爲四種
pc 程序計數器指針
optop 操做數棧頂指針
vars 局部變量第一變量指針
frame 當前執行環境指針
*全部的寄存器都是32位
7)棧結構
類加載後會爲每一個方法生成一個棧結構。
包含以下幾種區域:
局部變量:存儲局部變量。以32位爲單位存儲,long和double佔用兩個局部變量。vars寄存器經過偏移進行局部變量的訪問。
操做數棧:以32爲基礎單位。運算過程當中存儲操做數以及操做結果;調用方法時傳遞參數,並放置調用結果。機器指令取信息時,只從操做數棧取數據。
執行環境:存放解釋器所須要的各類信息,如局部變量指針,棧頂和棧底指針,上一次執行的方法。
動態連接:以符號指針的形式訪問方法和變量,而且把變量翻譯成存儲結構和偏移地址。
正常返回:正常返回時,調用方會獲得一個返回結果。進一步的設置調用方的寄存器,如把PC加一個適當的數,可以進行下一個指令的訪問。
異常捕捉:程序遇到相似於沒法找到class(動態連接錯),或者遇到空指針(運行時錯誤),接下來catch子句的匹配。
匹配原則:字節碼發生異常的地點是catch的範圍內,異常類型是catch的類型。
匹配順序:從第一個異常catch子句到最後一個子句,逐層查找。找到後處理catch異常塊代碼。最終匹配失敗,會執行最底層缺省塊異常。
執行iadd時,須要調用寄存器frame,經過frame找到操做數棧,彈出兩個操做數。
而後把計算結果,經過寄存器frame找到操做數棧,壓倒棧頂。
8)回收堆
java類實例的空間由解釋器進行分配和管理的。解釋器記錄對象的內存空間使用狀況,當內存再也不被使用時,由解釋器負責把內存空間回收到堆中。
右側爲自我理解:能夠理解Edan區域,survival區域,old區域。按步驟使用。
new時如今edan區域申請內存,不足時回收edan中不用對象。
內存仍是不足時,把部分活性不足的對象放置到survival中。
survival區域不足時,把部分活性不足的對象放置到old中。
old區域不足時,gc整個old區域。
gc後仍是不足時,報異常。
9)存儲區域-常量池
存儲: 類名,方法名,字段名稱,常量。
10)存儲池-方法區
存儲:方法執行的字節碼。
11)Java解釋器
拿着JAVA和C++對比,能夠理解以下:
Java源碼和C++源碼一樣爲高級語言;
Java編譯後文件爲二進制字節碼,C++編譯後文件爲二進制機器碼;
Java字節碼在JVM的java解釋其中執行,C++機器碼在CPU中執行;
Java解釋器是經過軟件實現的虛擬cpu,其最終還會把字節碼翻譯成機器碼在實際的CPU上執行;
只要運行平臺上實現了java解釋器,那麼java就能夠在這個平臺上執行,目前部分平臺不支持java,由於其沒有實現java解釋器;
12)運行數據
JVM啓動和退出時會建立和銷燬部分數據區域,線程建立和死亡時也會建立和銷燬部分數據。
包含:寄存器,棧,堆,常量池,方法區。
13)其餘
13.1)當開啓新的線程時,會爲線程建立java棧用以存放方法的調用狀態。注意,本地方法的調用狀態存放在棧結構的本地方法棧裏。
同時會爲線程設置PC 應用程序計數器寄存器,用以放置即將執行的命令。
13.2)JVM包括子系統(加載類子系統,指令運行引擎-解釋器),指令集,數據類型,五大存儲類型(寄存器,棧,堆,方法區,常量池)等。
13.3)JRE是java平臺,JavaRuntimeEnvironment,全部java程序的運行基礎。JDK安裝時,必須有一個JRE支持它,安裝了JDK後,會有一個JRE的目錄。
JVM是JRE的核心部分,它是虛擬的計算機。有本身的一套組件,如CPU(指令運行引擎-JAVA解釋器),寄存器,各類存儲器,指令集等。
參看link: 學習
https://baike.baidu.com/item/JVM/2902369操作系統