自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

JVM解毒之JVM與Java體系結(jié)構(gòu)

云計算 虛擬化
所謂虛擬機(Virtual Machine),就是一臺虛擬的計算機。它是一款軟件,用來執(zhí)行一系列虛擬計算機指令。大體上,虛擬機可以分為系統(tǒng)虛擬機和程序虛擬機。

 [[322350]]

你是否也遇到過這些問題?

  • 運行線上系統(tǒng)突然卡死,系統(tǒng)無法訪問,甚至直接OOM
  • 想解決線上JVM GC問題,但卻無從下手
  • 新項目上線,對各種JVM參數(shù)設(shè)置一臉懵逼,直接默認,然后就JJ了
  • 每次面試都要重新背一遍JVM的一些原理概念性東西

這段廣告語寫的好,趁著在家辦公學習下JVM,先列出整體知識點:

JVM解毒——JVM與Java體系結(jié)構(gòu)

Java開發(fā)都知道JVM是Java虛擬機,上學時還用過的VM也叫虛擬機,先比較一波。

虛擬機與Java虛擬機

所謂虛擬機(Virtual Machine),就是一臺虛擬的計算機。它是一款軟件,用來執(zhí)行一系列虛擬計算機指令。大體上,虛擬機可以分為系統(tǒng)虛擬機和程序虛擬機。

  • Visaual Box,VMware就屬于系統(tǒng)虛擬機,它們完全是對物理計算機的仿真,提供了一個可運行完整操作系統(tǒng)的軟件平臺
  • 程序虛擬機的典型代表就是Java虛擬機,它專門為執(zhí)行單個計算機程序而設(shè)計,在Java虛擬機中執(zhí)行的指令我們稱為Java字節(jié)碼指令

JVM 是什么

JVM 是 Java Virtual Machine(Java虛擬機)的縮寫,JVM是一種用于計算設(shè)備的規(guī)范,它是一個虛構(gòu)的計算機,是通過在實際的計算機上仿真模擬各種計算機功能來實現(xiàn)的。

Java虛擬機是二進制字節(jié)碼的運行環(huán)境,負責裝載字節(jié)碼到其內(nèi)部,解釋/編譯為對應(yīng)平臺的機器指令執(zhí)行。每一條Java指令,Java虛擬機規(guī)范中都有詳細定義,如怎么取操作數(shù),怎么處理操作數(shù),處理結(jié)果放在哪里。

特點

  • 一次編譯,到處運次(跨平臺)
  • 自動內(nèi)存管理
  • 自動垃圾回收功能

字節(jié)碼

我們平時所說的java字節(jié)碼,指的是用java語言編寫的字節(jié)碼,準確的說任何能在jvm平臺上執(zhí)行的字節(jié)碼格式都是一樣的,所以應(yīng)該統(tǒng)稱為jvm字節(jié)碼。

不同的編譯器可以編譯出相同的字節(jié)碼文件,字節(jié)碼文件也可以在不同的jvm上運行。

Java虛擬機與Java語言沒有必然的聯(lián)系,它只與特定的二進制文件格式——Class文件格式關(guān)聯(lián),Class文件中包含了Java虛擬機指令集(或者稱為字節(jié)碼、Bytecodes)和符號集,還有一些其他輔助信息。

Java代碼執(zhí)行過程

JVM解毒——JVM與Java體系結(jié)構(gòu)

JVM的位置

JVM是運行在操作系統(tǒng)之上的,它與硬件沒有直接的交互。

JDK(Java Development Kit) 是 Java 語言的軟件開發(fā)工具包(SDK)。JDK 物理存在,是 Java Language、Tools、JRE 和 JVM 的一個集合。

JVM解毒——JVM與Java體系結(jié)構(gòu)
JVM解毒——JVM與Java體系結(jié)構(gòu)

JVM整體結(jié)構(gòu)

JVM解毒——JVM與Java體系結(jié)構(gòu)

JVM的架構(gòu)模型

Java編譯器輸入的指令流基本上是一種基于棧的指令集架構(gòu),另外一種指令集架構(gòu)則是基于寄存器的指令集架構(gòu)。

兩種架構(gòu)之間的區(qū)別:

  • 基于棧式架構(gòu)的特點設(shè)計和實現(xiàn)更簡單,適用于資源受限的系統(tǒng);避開了寄存器的分配難題,使用零地址指令方式分配;指令流中的指令大部分是零地址指令,其執(zhí)行過程依賴于操作棧。指令集更小,編譯器容易實現(xiàn);不需要硬件支持,可移植性更好,更好實現(xiàn)跨平臺
  • 基于寄存器架構(gòu)的特點典型的應(yīng)用是X86的二進制指令集:比如傳統(tǒng)的PC以及Android的Davlik虛擬機;指令集架構(gòu)則完全依賴硬件,可移植性差;性能優(yōu)秀和執(zhí)行更高效;花費更少的指令去完成一項操作;大部分情況下,基于寄存器架構(gòu)的指令集往往都以一地址指令、二地址指令和三地址指令為主,而基于棧式架構(gòu)的指令集卻是以零地址指令為主

由于跨平臺性的設(shè)計,Java的指令都是根據(jù)棧來設(shè)計的。不同平臺CPU架構(gòu)不同,所以不能設(shè)計為基于寄存器的,優(yōu)點是跨平臺,指令集小,編譯器容易實現(xiàn),缺點是性能下降,實現(xiàn)同樣的功能需要更多的指令。

分析基于棧式架構(gòu)的JVM代碼執(zhí)行過程

進入class文件所在目錄,執(zhí)行javap -v xx.class反解析(或者通過IDEA插件Jclasslib直接查看),可以看到當前類對應(yīng)的code區(qū)(匯編指令)、本地變量表、異常表和代碼行偏移量映射表、常量池等信息。

 

JVM解毒——JVM與Java體系結(jié)構(gòu)

以上圖中的 1+2 為例說明:

  1. Classfile /Users/starfish/workspace/myCode/starfish-learning/starfish-learn/target/classes/priv/starfish/jvm/JVM1.class 
  2.   Last modified 2020-2-7; size 487 bytes 
  3.   MD5 checksum 1a9653128b55585b2745270d13b17aaf 
  4.   Compiled from "JVM1.java" 
  5. public class priv.starfish.jvm.JVM1 
  6.   SourceFile: "JVM1.java" 
  7.   minor version: 0 
  8.   major version: 52 
  9.   flags: ACC_PUBLIC, ACC_SUPER 
  10. Constant pool: 
  11.    #1 = Methodref          #3.#22         //  java/lang/Object."<init>":()V 
  12.    #2 = Class              #23            //  priv/starfish/jvm/JVM1 
  13.    #3 = Class              #24            //  java/lang/Object 
  14.    #4 = Utf8               <init> 
  15.    #5 = Utf8               ()V 
  16.    #6 = Utf8               Code 
  17.    #7 = Utf8               LineNumberTable 
  18.    #8 = Utf8               LocalVariableTable 
  19.    #9 = Utf8               this 
  20.   #10 = Utf8               Lpriv/starfish/jvm/JVM1; 
  21.   #11 = Utf8               main 
  22.   #12 = Utf8               ([Ljava/lang/String;)V 
  23.   #13 = Utf8               args 
  24.   #14 = Utf8               [Ljava/lang/String; 
  25.   #15 = Utf8               i 
  26.   #16 = Utf8               I 
  27.   #17 = Utf8               j 
  28.   #18 = Utf8               k 
  29.   #19 = Utf8               MethodParameters 
  30.   #20 = Utf8               SourceFile 
  31.   #21 = Utf8               JVM1.java 
  32.   #22 = NameAndType        #4:#5          //  "<init>":()V 
  33.   #23 = Utf8               priv/starfish/jvm/JVM1 
  34.   #24 = Utf8               java/lang/Object 
  35.   public priv.starfish.jvm.JVM1(); 
  36.     flags: ACC_PUBLIC 
  37.     Code: 
  38.       stack=1, locals=1, args_size=1 
  39.          0: aload_0        
  40.          1: invokespecial #1                  // Method java/lang/Object."<init>":()V 
  41.          4: return         
  42.       LineNumberTable: 
  43.         line 3: 0 
  44.       LocalVariableTable: 
  45.         Start  Length  Slot  Name   Signature 
  46.                0       5     0  this   Lpriv/starfish/jvm/JVM1; 
  47.  
  48.   public static void main(java.lang.String[]); 
  49.     flags: ACC_PUBLIC, ACC_STATIC 
  50.     Code: 
  51.       stack=2, locals=4, args_size=1 
  52.          0: iconst_1      //冒號前的數(shù)字表示程序計數(shù)器的數(shù),常量1入棧 
  53.          1: istore_1      //保存到1的操作數(shù)棧中,這里的1表示操作數(shù)棧的索引位置 
  54.          2: iconst_2       
  55.          3: istore_2       
  56.          4: iload_1       //加載 
  57.          5: iload_2        
  58.          6: iadd          //常量出棧,求和 
  59.          7: istore_3      //存儲到索引為3的操作數(shù)棧 
  60.          8: return         
  61.       LineNumberTable: 
  62.         line 6: 0 
  63.         line 7: 2 
  64.         line 8: 4 
  65.         line 9: 8 
  66.       LocalVariableTable: 
  67.         Start  Length  Slot  Name   Signature 
  68.                0       9     0  args   [Ljava/lang/String; 
  69.                2       7     1     i   I 
  70.                4       5     2     j   I 
  71.                8       1     3     k   I 
  72.       MethodParameters: length = 0x5 
  73.        01 00 0D 00 00  

JVM生命周期

虛擬機的啟動

Java虛擬機的啟動是通過引導類加載器(Bootstrap Class Loader)創(chuàng)建一個初始類(initial class)來完成的,這個類是由虛擬機的具體實現(xiàn)指定的。

虛擬機的執(zhí)行

  • 一個運行中的Java虛擬機有著一個清晰的任務(wù):執(zhí)行Java程序
  • 程序開始執(zhí)行時它才運行,程序結(jié)束時它就停止
  • 執(zhí)行一個所謂的Java程序的時候,真正執(zhí)行的是一個叫做Java虛擬機的進程
  • 你在同一臺機器上運行三個程序,就會有三個運行中的Java虛擬機。 Java虛擬機總是開始于一個main()方法,這個方法必須是公有、返回void、只接受一個字符串數(shù)組。在程序執(zhí)行時,你必須給Java虛擬機指明這個包含main()方法的類名。

虛擬機的退出

有以下幾種情況:

  • 程序正常執(zhí)行結(jié)束
  • 程序在執(zhí)行過程中遇到了異常或錯誤而異常終止
  • 由于操作系統(tǒng)出現(xiàn)錯誤而導致Java虛擬機進程終止
  • 某線程調(diào)用Runtime類或System類的exit方法,或Runtime類的halt方法,并且Java安全管理器也允許這次exit或halt操作
  • 除此之外,JNI(Java Native Interface)規(guī)范描述了用JNI Invocation API來加載或卸載Java虛擬機時,Java虛擬機的退出情況

Java和JVM規(guī)范

Java Language and Virtual Machine Specifications

JVM發(fā)展歷程

JDK 版本升級不僅僅體現(xiàn)在語言和功能特性上,還包括了其編譯和執(zhí)行的 Java 虛擬機的升級。

  • 1990年,在Sun計算機公司中,由Patrick Naughton、MikeSheridan及James Gosling領(lǐng)導的小組Green Team,開發(fā)出的新的程序語言,命名為Oak,后期命名為Java
  • 1995年,Sun正式發(fā)布Java和HotJava產(chǎn)品,Java首次公開亮相
  • 1996 年,JDK 1.0 發(fā)布時,提供了純解釋執(zhí)行的 Java 虛擬機實現(xiàn):Sun Classic VM。
  • 1997 年,JDK 1.1 發(fā)布時,虛擬機沒有做變更,依然使用 Sun Classic VM 作為默認的虛擬機
  • 1998 年,JDK 1.2 發(fā)布時,提供了運行在 Solaris 平臺的 Exact VM 虛擬機,但此時還是用 Sun Classic VM 作為默認的 Java 虛擬機,同時發(fā)布了JSP/Servlet、EJB規(guī)范,以及將Java分成J2EE、J2SE、J2ME
  • 2000 年,JDK1.3 發(fā)布,默認的 Java 虛擬機由 Sun Classic VM 改為 Sun HotSopt VM,而 Sun Classic VM 則作為備用虛擬機
  • 2002 年,JDK 1.4 發(fā)布,Sun Classic VM 退出商用虛擬機舞臺,直接使用 Sun HotSpot VM 作為默認虛擬機一直到現(xiàn)在
  • 2003年,Java平臺的Scala正式發(fā)布,同年Groovy也加入了Java陣營
  • 2004年,JDK1.5發(fā)布,同時JDK1.5改名為JDK5.0
  • 2006年,JDK6發(fā)布,同年,Java開源并建立了OpenJDK。順理成章,Hotspot虛擬機也成為了OpenJDK默認虛擬機
  • 2008年,Oracle收購BEA,得到了JRockit虛擬機
  • 2010年,Oracle收購了Sun,獲得Java商標和HotSpot虛擬機
  • 2011年,JDK7發(fā)布,在JDK1.7u4中,正式啟用了新的垃圾回收器G1
  • 2014年,JDK8發(fā)布,用元空間MetaSpace取代了PermGen
  • 2017年,JDK9發(fā)布,將G1設(shè)置為默認GC,替代CMS

Sun Classic VM

  • 世界上第一款商用 Java 虛擬機。1996年隨著Java1.0的發(fā)布而發(fā)布,JDK1.4時完全被淘汰;
  • 這款虛擬機內(nèi)部只提供解釋器;
  • 如果使用JIT編譯器,就需要進行外掛。但是一旦使用了JIT編譯器,JIT就會接管虛擬機的執(zhí)行系統(tǒng),解釋器就不再工作,解釋器和編譯器不能配合工作;
  • 現(xiàn)在hotspot內(nèi)置了此虛擬機

Exact VM

  • 它的執(zhí)行系統(tǒng)已經(jīng)具備了現(xiàn)代高性能虛擬機的雛形:如熱點探測、兩級即時編譯器、編譯器與解析器混合工作模式等;
  • 使用準確式內(nèi)存管理:虛擬機可以知道內(nèi)存中某個位置的數(shù)據(jù)具體是什么類型;
  • 在商業(yè)應(yīng)用上只存在了很短暫的時間就被更優(yōu)秀的 HotSpot VM 所取代

Sun HotSpot VM

  • 它是 Sun JDK 和 OpenJDK 中所帶的虛擬機,也是目前使用范圍最廣的 Java 虛擬機;
  • 繼承了 Sun 之前兩款商用虛擬機的優(yōu)點(如準確式內(nèi)存管理),也使用了許多自己新的技術(shù)優(yōu)勢,如熱點代碼探測技術(shù)(通過執(zhí)行計數(shù)器找出最具有編譯價值的代碼,然后通知 JIT 編譯器以方法為單位進行編譯;
  • Oracle 公司分別收購了 BEA 和 Sun,并在 JDK8 的時候,整合了 JRokit VM 和 HotSpot VM,如使用了 JRokit 的垃圾回收器與 MissionControl 服務(wù),使用了 HotSpot 的 JIT 編譯器與混合的運行時系統(tǒng)。

BEA JRockit VM

  • 專注于服務(wù)器端應(yīng)用,內(nèi)部不包含解析器實現(xiàn);
  • 號稱是世界上最快的JVM

IBM J9 VM

  • 全稱:IBM Technology for Java Virtual Machine,簡稱IT4J,內(nèi)部代號:J9
  • 市場定位于HotSpot接近,服務(wù)器端、桌面應(yīng)用、嵌入式等多用途VM
  • 目前是有影響力的三大商用虛擬機之一

虛擬機有很多,此外還有Azul VM、Liquid VM、Apache Harmony、TaobaoJVM、Graal VM等

 

責任編輯:武曉燕 來源: 今日頭條
相關(guān)推薦

2010-09-25 13:38:23

Inside JVM

2009-07-09 13:52:41

Inside JVM

2010-09-16 15:22:30

JVM體系結(jié)構(gòu)

2011-11-30 14:12:05

JavaJVM虛擬機

2010-09-27 09:43:07

JVM體系結(jié)構(gòu)

2020-05-12 22:24:44

JVM系統(tǒng)加載器

2017-09-20 08:48:09

JVM內(nèi)存結(jié)構(gòu)

2010-10-20 17:26:26

SQLServer線程

2009-06-26 15:58:28

EJB

2009-09-11 10:38:03

LINQ體系結(jié)構(gòu)

2009-07-15 13:46:26

Swing體系結(jié)構(gòu)

2012-02-06 17:22:44

MySQL

2014-07-23 09:33:52

2010-09-16 14:36:43

Java虛擬機

2010-09-26 16:55:31

JVM學習筆記

2020-07-29 14:15:04

JavaJvm算法

2010-09-27 08:38:49

JVM堆JVM棧

2009-07-08 14:23:40

JVM是什么

2010-06-21 14:51:14

ASON路由

2010-08-16 12:54:21

ASON路由技術(shù)
點贊
收藏

51CTO技術(shù)棧公眾號