JVM簡介 java
JVM是Java Virtual Machine(Java虛擬機)的縮寫,JVM是一種用於計算設備的規範,它是一個虛構出來的計算機,是經過在實際的計算機上仿真模擬各類計算機功能來實現的。web
Java語言的一個很是重要的特色就是與平臺的無關性。而使用Java虛擬機是實現這一特色的關鍵。通常的高級語言若是要在不一樣的平臺上運行,至少須要編譯成不一樣的目標代碼。而引入Java語言虛擬機後,Java語言在不一樣平臺上運行時不須要從新編譯。Java語言使用Java虛擬機屏蔽了與具體平臺相關的信息,使得Java語言編譯程序只需生成在Java虛擬機上運行的目標代碼(字節碼),就能夠在多種平臺上不加修改地運行。Java虛擬機在執行字節碼時,把字節碼解釋成具體平臺上的)執行。這就是Java的可以「一次編譯,處處運行」的緣由。spring
Tips: jvm至關於一個新的系統級軟件api
|
特色佈局
主要用來將*.class文件讀取到jvm的內存中(就是方法區)spa
裏面的不一樣部分都是用來保存java程序運行時的程序信息<數據+指令>
當class文件加載器加載了*.class文件後,這個文件的 類信息,常量,靜態變量,即時編譯後(jit)的代碼.
a.特色:線程共享(因爲保存的都是一些不可變信息)
b.保存信息格式:
1) 類(文件)class:
a. 類及其父類全限定名 (java.lang.Object沒有父類)
b. 類的類型 class 、 interface
c. 修飾符 public、protected、private
d. 實現接口的全限定名的列表 實現的接口列表
e. 常量池(final staic) 主要:string(使用final staic char[]實現的)||emun
f. 字段信息
g. 方法信息
h. 出常量外的靜態變量 static的method,class
i. Classloader引用
j. Class 引用
Tips:全限定名:完整的class地址 Eg:在org.spring.web包下的annotation.class其權限名:org.spring.web. annotation.class
2) 字段field:
a. 字段名
b. 字段類型 類型使用全限定名
c. 字段修飾符 基本類型和對象
a) 訪問修飾: public、private、protected
b) 靜態: static
c) 常量: final
d) Jndi: transient
e) 線程: volatitile
3) 方法method:
a) 方法名: 全限定名
b) 返回類型: 全限定名
c) 參數信息: 參數列表:由全限定名
d) 修飾符:
a) 訪問修飾: public、private、protected
b) 靜態: static
c) 常量: final
d) 線程: synchronized
e) 本地: native
f) 抽象: abstract
若是不是native和abstract還會保存一下信息
1. 方法的字節碼
2. 本變量表和操做數棧的大小
3. 異常表
c.String常量池:
存放數組和對象實例(new)的地方,gc的主要區域。
主要分區
名稱 | 個數 | 大小比(default) |
年輕代 | 1 | 4 |
年老代 | 1 | 1 |
年輕代
名稱 | 個數 | 大小(default) |
eden區 | 1 | 8 |
survivor區 | 2 | 2 |
直接內存:
調用本地庫來操做分配系統的內存
對象訪問:
這是堆的主要功能,每次new都會分配一個對象大小的內存空間。而且在java棧中有一個這個對象的引用。還能夠經過這個引用查找存放在method area區的對象文件(.class)的全部信息<也就是其類的信息>。
Reference在Java虛擬機中定義爲指向對象的引用
1.一種實現是Reference直接存儲對象在堆內的地址,對象的類型信息能夠在對象在堆中的內存佈局中存儲,如存儲在對象內存的開頭等。
2.另外一種實現是Reference指向一個句柄表中的一個位置,句柄中保存了對象的實際位置及它對應的類型信息。使用句柄的好處是當在內存中移動對象的位置時,只須要更新句柄表中的內容,不須要改變引用值,但會多一次內存訪問開銷,直接引用的優缺點與此相反。
執行本地方法。
例如:系統的文件系統,系統的網絡系統。
相似於PC寄存器,是一塊較小的內存區域,經過程序計數器中的值尋找要執行的指令的字節碼,因爲多線程間切換時要恢復每個線程的當前執行位置,因此每一個線程都有本身的程序計算器。這一個區域不會有OutOfMemeryError。當執行Java方法時,這裏存儲的執行的指令的地址,若是執行的是本地方法,這裏的值是Undefined
虛擬機棧也是線程私有的,每建立一個線程,虛擬機就會爲這個線程建立一個虛擬機棧,虛擬機棧表示Java方法執行的內存模型,每調用一個方法,就會生成一個棧幀(Stack Frame)用於存儲方法的本地變量表、操做棧、方法出口等信息,當這個方法執行完後,就會彈出相應的棧幀。
若是請求的棧的深度過大,虛擬機可能會拋出StackOverflowError異常,若是虛擬機的實現中容許虛擬機棧動態擴展,當內存不足以擴展棧的時候,會拋出OutOfMemoryError異常
每個線程都會
棧幀:
1.局部變量區
局部變量區被組織一個一個從0開始的字數組,byte、short、char在存儲前被轉換爲int,boolean也被轉換爲int,0表示false,非0表示true,long和double佔據兩個字長。
2.操做數棧
操做數棧也被組織爲一個字數組,但不一樣於局部變量區,它不是經過數組下標訪問的,而是能過棧的Push和Pop操做,前一個操做Push進的數據能夠被下一個操做Pop出來使用。
3.棧數據區
a) 常量池中的數據解析
b) 方法執行完後處理方法返回,會恢復調用方法現場
c) 方法執行過程當中拋出異常時的異常處理,存儲有一個異常表,當出現異常時虛擬機查找相應的異常表看是否有對應的Catch語句,若是沒有就拋出異常終止
JIT Compiler: just-in-time Compiler及時編譯
Garbage Collector:垃圾回收
這裏很是粗糙的模擬下jvm的運行方式