主頁 > 後端開發 > JVM虛擬機我來了~~~

JVM虛擬機我來了~~~

2022-11-22 07:07:09 後端開發

虛擬機

1.1 發展歷程

1.1.1 java往事

? Java誕生在一群懶惰、急躁而傲慢的程式天才之中,

? 1990年12月,Sun的工程師Patrick Naughton被當時糟糕的Sun C++工具折磨的快瘋了,他大聲抱怨,并威脅要離開Sun轉投當時在Steve Jobs領導之下的NeXT公司,領導層為了留住他,給他一個機會,啟動了一個叫做Stealth(秘密行動)的專案,

? 隨著James Gosling等人的加入,這個專案更名為Green,其目標是使用C++為嵌入式設備開發一種新的基礎平臺技術,James Gosling本人負責開發一個編輯器,正如人們事后分析的那樣,這位天才的程式員太懶惰,所以沒有把C++學好,開發中碰了一頭包,于是他決定開發一種新的編程語言,他把這種語言命名為C++++--,意思是C++ “加上一些好東西,減去一些壞東西”,顯然這個糟糕的名字不可能長久,于是很快這種頗受同伴喜愛的小語言被命名為Oak,

? 到了1992年9月,Oak語言連同Green OS和一些應用程式一起發布在稱做Start 7的小設備上,有了第一次精彩的亮相,隨后,Sun開了一家名為FirstPerson的公司,整個團隊被轉移到這家公司里研發機頂盒,以投標時代華納公司的一個專案,這幫天才被技術狂熱所鼓舞,開發出了一個高互動性的設備,結果沒想到時代華納公司和有線電視服務商并不愿意用戶擁有那么大的控制權,從而在競標之戰中敗給了SGI,

? Sun無奈地關閉了FirstPerson,召回了整個團隊,java的出路卻沒有因此而斷送,隨著互聯網發展的涌動,java開始離開嵌入式小設備,往互聯網傾斜,1994年,Oak被命名為Java,回到了激情澎湃的IT產業,抓住互聯網的大潮,從此一發不可收拾,

? 剩下的事情,大家都知道了……

1.1.2 版本迭代

  • 1991 年,James Gosling 博士發布產品 Oak( 橡樹),這是 Java 語言的前身,

  • 1995 年,Oak 語言改名為 Java,

  • 1996 年,JDK(Java開發所使用的工具包)1.0 發布,提供了純解釋執行的 Java 虛擬機實作:Sun Classic VM,

  • 1997 年,JDK1.1 發布,代表技術有:JDBC、JavaBeans、內部類、反射,

  • 1998 年,JDK1.2 發布,Java 技術體系被拆分為 J2SE、J2EE、J2ME 三大體系,

    • 2000 年,JDK1.3 發布,默認的 Java 虛擬機由 Sun Classic VM 改為 HotSopt,
  • 2002 年,JDK1.4 發布,Java 真正走向成熟,代表技術有:正則運算式、NIO等,

  • 2004 年,JDK5.0 發布,對語法易用性做了很大改進,新增了泛型、列舉等,代表技術有:并發包等,

  • 2006 年,JDK6.0 發布,將 J2EE/J2SE/J2ME 的命名方式改為 Java SE 6、Java EE 6、Java ME 6,

  • 2009 年,Sun 公司因為經營不善被 Oracle 公司收購,

  • 2011 年,JDK7 發布,

  • 2013 年,JDK8(LTS) 發布,函式式編程,lamda運算式,

  • 2017年,JDK9

  • 2018年,JDK 10,11(LTS)正式發布

  • 2019年,JDK 12,13

  • 2020年,JDK 14,15

  • 2021年,JDK 16,17(LTS)

附:sun與微軟的軼事
java誕生的1995年,正是微軟在軟體產業地位達到巔峰的時代,但是這個初出茅廬的毛頭小子硬是引起了微軟帝國的關注,所以96年微軟就向sun申請了java認證,
微軟的加持確實推動了人們對java的信心和興趣,
但是好景不長,從1997年發布Visual J++的第一個版本開始,微軟就開始在Java中摻入自己的私有擴展,這毫無疑問引起Sun的高度重視,
1997年10月,Sun向美國加州地方法院起訴微軟公司違反兩公司就微軟使用Java技術所簽定的合同,指控微軟公司在自己的Java產品中做了“不恰當的修改”,違反了合同中承諾向用戶提供Java兼容產品的條款,
這一官司一直打到了2001年1月雙方達成和解,
到了2001年7月,微軟公布新版的Windows XP將不再支持Sun的JVM,并且推出了.NET平臺與Java分庭抗禮,
當然目前.net用的人少了,這是后話,

file

1.1.3 兩種jdk

openjdk vs oraclejdk:

  1. Oracle JDK將更多地關注穩定性,它重視更多的企業級用戶,而OpenJDK經常發布以支持其他特性,不太穩定,
  2. Oracle JDK支持長期發布的更改(LTS),而Open JDK僅支持計劃和完成下一個發行版,
  3. Oracle JDK根據二進制代碼許可協議獲得許可,而OpenJDK根據GPL v2許可獲得許可,
  4. 2019年1月之后發布的Oracle Java SE 8的公開更新將無法用于商業,但是,OpenJDK是完全開源的,可以自由使用,
  5. Oracle JDK的構建程序基于OpenJDK,因此OpenJDK與Oracle JDK之間沒有技術差異,
  6. 頂級公司正在使用Oracle JDK,Open JDK不太受歡迎,
  7. Oracle JDK具有良好的GC選項和更好的渲染器,而OpenJDK具有更少的GC選項
  8. 在回應性和JVM性能方面,Oracle JDK提供了更好的性能,
  9. Oracle JDK在運行JDK時不會產生任何問題,而OpenJDK有時會產生一些問題,
  10. Oracle JDK將從其10.0.X版本將收費,用戶必須付費或必須依賴OpenJDK才能使用其免費版本,
  11. Oracle JDK完全由Oracle公司開發,而Open JDK專案由IBM,Apple,SAP AG,Redhat等頂級公司加入和合作,

1.2 JVM體系

file

  • JDK(Java Development Kit)是 Java語言的軟體開發工具包,也是整個java開發的核心,它包含了JRE和開發工具包

  • JRE(Java Runtime Environment),Java運行環境,包含了JVM和Java的核心類別庫(Java API)

  • JVM(Java Virtual Machine),Java虛擬機,它是運行在作業系統之上的,它與硬體沒有直接的互動

所謂“一次編碼,隨處運行“正是基于不同系統下的jvm幫你掩蓋了系統之間介面的差異:

file

總結

jdk是開發人員的工具包,它包含了java的運行環境和虛擬機,而一次撰寫到處運行就是基于jvm

1.3 各種虛擬機

1.3.1 清單

1、Sun Classic VM

? 世界上第一款商用 Java 虛擬機,

1996年隨著Java1.0的發布而發布,JDK1.4時完全被淘汰

2、BEA JRockit

專注于服務端應用,號稱是世界上最快的JVM

? 后來被 Oracle收購;Oracle JRockit (原來的 Bea JRockit)

3、IBM公司的 J9VM

全稱:IBM Technology for Java Virtual Machine,簡稱IT4J,內部代號:J9

是 IBM 自己開發的一款 JVM

市場定位于HotSpot接近,服務器端、桌面應用、嵌入式等多用途VM

4、HotSpot VM(現在最常用)

? 它是Sun JDK和OpenJDK中所帶的虛擬機,也是目前使用范圍最廣的Java虛擬機,

5、其他

(TaobaoJVM 、Graal VM、Azul VM、Liquid VM、Apache Harmony、)虛擬機

1.3.2 查看

shawn@macpro:~ > java -version
java version "1.8.0_181"
Java(TM) SE Runtime Environment (build 1.8.0_181-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
  • hotspot虛擬機

  • Client VM是專門為快速啟動和小記憶體(small footprints)而優化的,像GUI就很適合

  • Server VM是專門為高性能應用而優化的,如服務器應用

  • 版本是基于tag為1.8.0_181

1.4 jvm整體架構

1.4.1 java運行程序

file

1.原始碼編譯:通過Java原始碼編譯器將Java代碼編譯成JVM位元組碼(.class檔案)

2.類加載:通過ClassLoader及其子類來完成JVM的類加載

3.類執行:位元組碼被裝入記憶體,進入JVM虛擬機,被解釋器解釋執行

1.4.2 jvm模型

file

由上面的圖可以看出,JVM虛擬機中主要是由三部分構成,分別是類加載子系統、運行時資料區、執行引擎,

類加載子系統

Java虛擬機把描述類的資料從Class檔案加載到記憶體,并對資料進行校驗、轉換決議和初始化,最終形成可以被虛擬機直接使用的Java型別,

運行時資料區

Java虛擬機在執行Java程式的程序中會把它所管理的記憶體劃分為若干個不同的資料區域,

這些區域有各自的用途,以及創建和銷毀的時間,有的區域隨著虛擬機行程的啟動而一直存在,有些區域則是依賴用戶執行緒的啟動和結束而建立和銷毀,

執行引擎

執行引擎用于執行JVM位元組碼指令,主要有兩種方式,分別是解釋執行和編譯執行,區別在于,解釋執行是在執行時翻譯成虛擬機指令執行,而編譯執行是在執行之前先進行編譯再執行,

解釋執行啟動快,執行效率低,編譯執行,啟動慢,執行效率高,

垃圾回收器就是自動管理運行資料區的記憶體,將無用的記憶體占用進行清除,釋放記憶體資源,

本地方法庫、本地庫介面

在jdk的底層中,有一些實作是需要呼叫本地方法完成的(使用c或c++寫的方法),就是通過本地庫介面呼叫完成的,比如:System.currentTimeMillis()方法,

2、類檔案結構

了解jvm后續的一切動作,先從位元組碼開始,它是一切發生的源頭,

2.1 測驗案例

2.1.1 源代碼

package com.itheima.jvm.demo;

public class ClassStruct {

    private static String name = "JVM";

    public static void main(String[] args) {
        System.out.println("Hello " + name);
    }

}

2.1.2 編譯

1)maven定義編譯的版本

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

2)編譯

mvn clean compile

2.2 位元組碼結構

2.2.1 二進制概覽

1)vscode打開

file

2)class檔案是一個二進制檔案,轉化后是16進制展示,實際上class檔案就是一張表,它由以下資料項構成,這些資料項從頭到尾嚴格按照以下順序排列:

型別 名稱 數量 描述
u4 magic 1 魔數
u2 minor_version 1 次版本號
u2 major_version 1 主版本號
u2 constant_pool_count 1 常量個數
cp_info constant_pool constant_pool_count - 1 具體常量
u2 access_flags 1 訪問標志
u2 this_class 1 類索引
u2 super_class 1 父類索引
u2 interfaces_count 1 介面索引
u2 interfaces interfaces_count 具體介面
u2 fields_count 1 欄位個數
field_info fields fields_count 具體欄位
u2 methods_count 1 方法個數
method_info methods methods_count 具體方法
u2 attributes_count 1 屬性個數
attribute_info attributes attributes_count 具體屬性

3)圖示如下:

file

2.2.2 魔數與版本

1)魔數:

CAFEBABE,咖啡寶寶,固定的,

file

2)版本號:

34,換成10進制就是52

file

jdk的版本標記映射關系:

file

說明編譯用的是jdk8,我們改成1.6,重新執行 mvn clean compile ,再來查看class檔案試試:

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

擴展

在開發中,經常會遇到類似Unsupported major.minor version 51.0的錯誤,一般情況下都是JDK版本不匹配造成的,
雖然jdk代碼在執行時基本上向下兼容,但是!開發環境和服務器環境jdk最好一致,不要嘗試這個坑,

區分和理解兩個環境:編譯環境,運行環境

2.2.3 常量池

再往下遵從相同的規律: 計數器(標注后面有多少個) + 對應個數的結構體

我們以常量池為例:

1)位置

file

2)結構說明

常量池記錄了jvm內的一堆常量資訊,這部分由 【2個位元組計數】 + 【n個cp_info結構】組成

file

其中cp_info有多種型別:

  • 直接型別,存的就是當前值,這種像Integer,Long等長度都是確定的
  • 參考型別,存的是指向其他位置的指標

file
附:綠色代表指標,橙色代表直接型別

3)案例

下面以String為例,String是一種參考類,它會指向一個utf8型別來存盤真實的資訊

jdk提供了一個工具,javap,可以查看常量串列的詳細內容:

javap -v ClassStruct.class

file

2.2.4 其他資訊

1)說明

常量池之后,是緊挨的一系列資訊,這些資訊大同小異,無非就是值、或者參考

(參考上面2.3.3里的表格和圖例)

  • 訪問標記:public abstract 等資訊
  • 類索引,class型別,最終指向一個utf8,標記當前類的名字
  • 父類,同上
  • 介面,2位元組記錄數量,后面記錄多個介面型別
  • 接下來是欄位、方法、屬性,都是2位元組記錄后面多少個,后面緊跟對應的結構體型別

2)注意事項

要看懂javap后的格式,明白這些格式,可以輕松看懂class結構

file

型別 識別符號 案例 說明
陣列 [ [Ljava.lang.String String陣列
物件 L Lcom.test.Demo
基本型別 大寫字母開頭 B=byte,I=int……

組合型別

型別 案例 說明
類里的屬性、欄位、方法等 com.test.Demo.name:Ljava.lang.String 英文點號隔開
標識什么型別 com.test.Demo.getName:()Ljava.lang.String 英文冒號隔開
方法 (引數型別)回傳值型別 英文括弧,后面是回傳值型別

3)實體分析

file

本文由傳智教育博學谷教研團隊發布,

如果本文對您有幫助,歡迎關注點贊;如果您有任何建議也可留言評論私信,您的支持是我堅持創作的動力,

轉載請注明出處!

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/537675.html

標籤:其他

上一篇:mybatis流式查詢與分頁插件

下一篇:java基礎篇——流程控制

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more