日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

初步了解java虚拟机

發(fā)布時(shí)間:2023/12/10 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 初步了解java虚拟机 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1. jdk, jre, jvm 關(guān)系

基本介紹:
JDK(Java Development Kit)是針對(duì)Java開發(fā)員的產(chǎn)品,是整個(gè)Java的核心,包括了Java運(yùn)行環(huán)境JRE、Java工具和Java基礎(chǔ)類庫(kù)。
Java Runtime Environment(JRE)是運(yùn)行JAVA程序所必須的環(huán)境的集合,包含JVM標(biāo)準(zhǔn)實(shí)現(xiàn)及Java核心類庫(kù)。
JVM是Java Virtual Machine(Java虛擬機(jī))的縮寫,是整個(gè)java實(shí)現(xiàn)跨平臺(tái)的最核心的部分,能夠運(yùn)行以Java語(yǔ)言寫作的軟件程序。

1、JDK

JDK是java開發(fā)工具包,在其安裝目錄下面有六個(gè)文件夾、一些描述文件、一個(gè)src壓縮文件。bin、include、lib、 jre這四個(gè)文件夾起作用,demo、sample是一些例子。可以看出來(lái)JDK包含JRE,而JRE包含JVM。

bin:最主要的是編譯器(javac.exe)*
include:java和JVM交互用的頭文件
lib:類庫(kù)
jre:java運(yùn)行環(huán)境(注意:這里的bin、lib文件夾和jre里的bin、lib是不同的)
總的來(lái)說(shuō)JDK是用于java程序的開發(fā),而jre則是只能運(yùn)行class而沒(méi)有編譯的功能。
JDK是提供給Java開發(fā)人員使用的,其中包含了java的開發(fā)工具,也包括了JRE。所以安裝了JDK,就不用在單獨(dú)安裝JRE了。 其中的開發(fā)工具包括編譯工具(javac.exe)打包工具(jar.exe)等

2、JRE

JRE是指java運(yùn)行環(huán)境。光有JVM還不能成class的執(zhí)行,因?yàn)樵诮忉宑lass的時(shí)候JVM需要調(diào)用解釋所需要的類庫(kù)lib。在JDK的安裝目錄里你可以找到j(luò)re目錄,里面有兩個(gè)文件夾bin和lib,在這里可以認(rèn)為bin里的就是jvm,lib中則是jvm工作所需要的類庫(kù),而jvm和 lib和起來(lái)就稱為jre。所以,在你寫完java程序編譯成.class之后,你可以把這個(gè).class文件和jre一起打包發(fā)給朋友,這樣你的朋友就可以運(yùn)行你寫程序了。
包括Java虛擬機(jī)(JVM Java Virtual Machine)和Java程序所需的核心類庫(kù)等,
如果想要運(yùn)行一個(gè)開發(fā)好的Java程序,計(jì)算機(jī)中只需要安裝JRE即可。

3、JVM

JVM就是我們常說(shuō)的java虛擬機(jī),它是整個(gè)java實(shí)現(xiàn)跨平臺(tái)的最核心的部分,所有的java程序會(huì)首先被編譯為.class的類文件,這種類文件可以在虛擬機(jī)上執(zhí)行,也就是說(shuō)class并不直接與機(jī)器的操作系統(tǒng)相對(duì)應(yīng),而是經(jīng)過(guò)虛擬機(jī)間接與操作系統(tǒng)交互,由虛擬機(jī)將程序解釋給本地系統(tǒng)執(zhí)行。

可以理解為是一個(gè)虛擬出來(lái)的計(jì)算機(jī),具備著計(jì)算機(jī)的基本運(yùn)算方式,它主要負(fù)責(zé)將java程序生成的字節(jié)碼文件解釋成具體系統(tǒng)平臺(tái)上的機(jī)器指令。讓具體平臺(tái)如window運(yùn)行這些Java程序。

JVM:將字節(jié)碼文件轉(zhuǎn)成具體系統(tǒng)平臺(tái)的機(jī)器指令。
JRE:JVM+Java語(yǔ)言的核心類庫(kù)。
JDK:JRE+Java的開發(fā)工具。

二、了解以下未來(lái)jdk的新技術(shù)發(fā)展

  • Java 13 處于創(chuàng)新者階段,Java 11 處于早期采用者階段,Java 8 處于晚期大眾階段。
  • Java 11 將是未來(lái) Java 用戶的最可能選項(xiàng);

    如果一個(gè)公司對(duì)大堆棧 GC 能力、延遲 SLA 等方面要求沒(méi)有那么高,就沒(méi)有足夠動(dòng)力去做相關(guān)升級(jí),也未必有技術(shù)力量解決版本評(píng)估、兼容性修正等現(xiàn)實(shí)問(wèn)題;

    Java 新版本升級(jí)在中國(guó)的宣傳還是不夠,如果很多企業(yè)看不到技術(shù)升級(jí)的紅利,勢(shì)必也影響升級(jí)的積極性。

  • OpenJDK 處于創(chuàng)新者階段。
  • 雖然國(guó)內(nèi)很多頭部廠商都在定制 OpenJDK,但是目前定制 OpenJDK 被采用范圍還都有限,主體使用還是 Oracle JDK(根據(jù)《JVM 生態(tài)系統(tǒng)報(bào)告 2018》調(diào)查顯示,70% 的開發(fā)者選擇使用 Oracle JDK,21% 的開發(fā)者選擇使用 OpenJDK);

    廠商是否轉(zhuǎn)向 OpenJDK,還有一個(gè)重要考量因素就是看他們是否愿意付費(fèi)使用 OracleJDK,如果不是的話,未來(lái) OpenJDK 可能會(huì)逐漸取代 Oracle JDK,目前國(guó)內(nèi)頭部廠商都在 OpenJDK 上有所動(dòng)作; (對(duì)于參與 OpenJDK 的國(guó)內(nèi)頭部廠商來(lái)說(shuō),可能他們的看法更加積極,他們把 OpenJDK 定義在早期大眾階段)

    大家在公有云、私有云等方面的競(jìng)爭(zhēng)格局,深刻影響著在 OpenJDK 上的競(jìng)爭(zhēng)格局;

    OpenJDK 很可能被認(rèn)為是一種退?求其次的選擇。

  • 非 Hotspot JDK 生產(chǎn)實(shí)踐——Graal VM、IBM OpenJ9 處于早期采用者階段。
  • Graal VM 目前還尚不可知其兼容性情況以及明確的商業(yè)化條款;

    Graal VM 的部分技術(shù),例如,基于 Java 語(yǔ)言開發(fā)的 JIT 引擎,可能會(huì)成為未來(lái) OpenJDK 的基礎(chǔ)技術(shù);

    在國(guó)內(nèi),懷疑 Graal VM、IBM OpenJ9 進(jìn)入普遍生產(chǎn)實(shí)踐的可能性會(huì)比較低。

  • Lambda /Stream 處于晚期大眾階段、Vector API 處于創(chuàng)新者階段。
  • Lambda 語(yǔ)法以及 Stream API 也在開發(fā)人員的?常?作中?泛地運(yùn)用,并且沒(méi)有看到語(yǔ)法回退的趨勢(shì);

    Vector API 等前沿特性,有能力的公司有限,抑制了對(duì)其有需求的公司或者場(chǎng)景。

  • Kotlin 處于早期大眾階段,Scala 和 Groovy 處于晚期大眾階段。
  • Groovy 已快成為明日黃花,往昔的光芒逐漸地被后起之秀 Kotlin 替代;

    Scala 在適合的領(lǐng)域做王者就夠了,主流不主流沒(méi)那么重要;

    Kotlin 被谷歌強(qiáng)推,谷歌支持的基本上都成功了,但是對(duì) Kotlin 未來(lái)發(fā)展空間還是表示懷疑;

    網(wǎng)上很多文章都在鼓吹,說(shuō) Kotlin 最終會(huì)取代 Java 成為新一代 JVM 主流語(yǔ)言, 但是從誕生到現(xiàn)在,好像依然沒(méi)有語(yǔ)言能取代 Java。

  • 微服務(wù)框架:Spring Boot 和 Spring Cloud 進(jìn)入晚期大眾階段;ServiceComb 處于早期采用者階段;Apache Dubbo 處于晚期大眾階段;Tars 處于早期大眾階段。
  • 微服務(wù)技術(shù)處于早期大眾與晚期大眾之間,新的微服務(wù)開發(fā)框架需要技術(shù)突破和創(chuàng)新,不然已經(jīng)難有一席之地;

    Java 不再是微服務(wù)唯一的選擇;

    在技術(shù)多元化的今天,支持多語(yǔ)言的微服務(wù)開發(fā)框架是個(gè)必須品。

    技術(shù)采用生命周期解讀
    在上一章節(jié)我們已經(jīng)先把各位專家的觀點(diǎn)和結(jié)論拋了出來(lái),但是結(jié)論背后還需要很關(guān)鍵的原因解讀,所以這一章節(jié)就按照 Java/JVM、不同層次的主流框架、微服務(wù)這三個(gè)部分,來(lái)逐一呈現(xiàn)。

    Java/JVM

    其實(shí)在 Java 版本方面,各位專家的觀點(diǎn)完全一致:Java 13 處于創(chuàng)新者階段,Java 11 處于早期采用者階段,Java 8 處于晚期大眾階段。

    在 InfoQ 面向開發(fā)者的 Java 使用版本調(diào)查中,毫無(wú)懸念,在參與問(wèn)卷調(diào)研的開發(fā)者中,88.7% 正在使用 Java8 版本,這些人當(dāng)中只有 35% 有升級(jí)計(jì)劃,剩余 65% 并沒(méi)有升級(jí)計(jì)劃。

    楊曉峰認(rèn)為這一情況也正常:Java8 在可預(yù)見的將來(lái)依然會(huì)是生產(chǎn)的主體,放在晚期大眾階段是合理的。但是對(duì)于很多頭部廠商來(lái)說(shuō),Java11 或者再后續(xù)版本,有可能陸續(xù)出現(xiàn)一定規(guī)模的生產(chǎn)化部署。他認(rèn)為這樣的趨勢(shì)只會(huì)在頭部公司發(fā)生,如果一個(gè)公司對(duì)大堆棧 GC 能力、延遲 SLA 等方面要求沒(méi)有那么高,就沒(méi)有足夠動(dòng)力去做相關(guān)升級(jí),也未必有技術(shù)力量解決版本評(píng)估、兼容性修正等現(xiàn)實(shí)問(wèn)題。所以結(jié)論就是:Java11 處于早期采用者階段。

    對(duì)此黃飛補(bǔ)充:也正是因?yàn)?Java11 處于早期采用者階段,因此相關(guān)的資料較少,遇到問(wèn)題會(huì)有比較高的學(xué)習(xí)成本,例如 JFR 對(duì) 11 的支持,JMC 對(duì) Java11 的分析能力較弱。

    而對(duì)于 Java 13,小馬哥認(rèn)為該版本在新 GC 算法的提升以及 Socket 實(shí)現(xiàn)上的變化還是非常令?期待的,因此 Java 13 排在創(chuàng)新者之列。

    對(duì)于 Java 的升級(jí),Oracle 宣布從 Java 9 開始每半年將更新一個(gè) Java 大版本——Java 11 是長(zhǎng)期支持(Long-Term -Support, LTS)版本,Java 9、10 則成了過(guò)渡版本(non?LTS),因此,陳楚暉不建議用戶在生產(chǎn)中使用 Java 9、10。在他看來(lái),小版本升級(jí)相對(duì)風(fēng)險(xiǎn)是比較小的,而大版本變更則會(huì)有可能需要更改大量的代碼,這也是為什么這么多人還在堅(jiān)持用 Java8,而不去更新 Java 11、12、或者 13 的原因。

    對(duì)于開發(fā)者升級(jí) Java 動(dòng)力不足的原因,李三紅的解釋更為詳細(xì),他認(rèn)為有兩個(gè)原因:

    敏捷的基礎(chǔ)底層架構(gòu)對(duì)軟件升級(jí)的支持,企業(yè)對(duì)底層架構(gòu)的重視程度也是 Java 升級(jí)的一個(gè)很關(guān)鍵原因。中國(guó)的企業(yè)業(yè)務(wù)發(fā)展都很快,但是其實(shí)很多對(duì)底層架構(gòu)的支持和重視是不足夠的。底層架構(gòu)是否在企業(yè)內(nèi)部被統(tǒng)一強(qiáng)管控,是否很容易支持不同軟件版本的灰度,并能通過(guò)有效的預(yù)發(fā)測(cè)試,覆蓋軟件升級(jí)不兼容等帶來(lái)的不確定性,這都考驗(yàn)著軟件升級(jí)的難度。

    另外一點(diǎn),如果企業(yè)享受不到技術(shù)升級(jí)帶來(lái)的紅利,包括性能、編程效率等多方面提升,勢(shì)必也影響升級(jí)的積極性。

    從此次 InfoQ 面向開發(fā)者的調(diào)研來(lái)看,對(duì)于目前 Java 的新特性和發(fā)展方向,56% 的開發(fā)者認(rèn)為可以解決當(dāng)前的主要業(yè)務(wù)挑戰(zhàn),24% 開發(fā)者的觀點(diǎn)是不能。這也從另一層面表明:Java 經(jīng)常被吐槽演進(jìn)太慢,但是業(yè)界對(duì)新版本的采用并不十分積極,這可能反映了 Java/JVM 發(fā)展與開發(fā)者的實(shí)際需求存在某種脫節(jié)。

    OpenJDK 定制版或者公開發(fā)行版

    由于 Oracle 宣布 2019 年伊始,Oracle JDK 8 以及更?版本在服務(wù)器端部署不再免費(fèi),因此 OpenJDK 就成為了大多數(shù) Java 用戶的選項(xiàng)。根據(jù)《JVM 生態(tài)系統(tǒng)報(bào)告 2018》調(diào)查顯示,70% 的開發(fā)者選擇使用 Oracle JDK,21% 的開發(fā)者選擇使用 OpenJDK。 陳楚暉也介紹了國(guó)內(nèi)的情況:目前國(guó)內(nèi)開發(fā)者使用最多的依舊是 Oracle JDK,其次是 IBM JDK,也有部分企業(yè)采用 OpenJDK。

    對(duì)于 OpenJDK 的技術(shù)采用生命周期劃分,專家們有一些觀點(diǎn)上的不一致,楊曉峰認(rèn)為雖然國(guó)內(nèi)很多頭部廠商都在定制 OpenJDK,但是目前定制 OpenJDK 被采用范圍還都有限,這也跟上文數(shù)據(jù)結(jié)果吻合,所以他會(huì)把 OpenJDK 歸在創(chuàng)新者階段。

    但是對(duì)于參與 OpenJDK 的國(guó)內(nèi)廠商來(lái)說(shuō),可能看法更加積極。在李三紅看來(lái):廠商是否轉(zhuǎn)向 OpenJDK,還有一個(gè)重要考量因素就是看他們是否愿意付費(fèi)使用 OracleJDK,如果不是的話,未來(lái) OpenJDK 可能會(huì)逐漸取代 Oracle JDK,目前國(guó)內(nèi)頭部廠商都在 OpenJDK 上有所動(dòng)作,所以他把 OpenJDK 定義在早期大眾階段。阿里巴巴使用并開源了 OpenJDK 長(zhǎng)期支持版本 Dragonwell,目前阿里巴巴大部分的應(yīng)用運(yùn)行在 Dragonwell 8, 有些已經(jīng)運(yùn)行在 Dragonwell 11。

    據(jù)來(lái)自美團(tuán)的吳革介紹:美團(tuán)現(xiàn)階段正在測(cè)試基于 OpenJDK 的 MtJDK,作為美團(tuán) JDK 基礎(chǔ)服務(wù)。此外,美團(tuán)主要會(huì)關(guān)注 Redhat 和 Amazon 的升級(jí)。由于 Azul 沒(méi)有公開 OpenJDK 源代碼,所以美團(tuán)沒(méi)有基于 Azul 進(jìn)行研發(fā)。

    3. jvm種類, 我們使用的是哪一種,特點(diǎn)?

    我們廣泛使用的是HotSpot Vm

  • Sun Classic Vm
    第一款商用的虛擬機(jī),只能使用純解釋器的方式來(lái)執(zhí)行java代碼。已經(jīng)過(guò)時(shí)了。

  • Exact Vm
    1)Exact的全稱是Exact Memory Management 準(zhǔn)確式內(nèi)存管理(虛擬機(jī)可以知道內(nèi)存中某個(gè)位置的數(shù)據(jù)是什么內(nèi)存的)。

  • 2)編譯器和解釋器混合工作以及兩級(jí)即時(shí)編譯器。

    3)只在Solaris平臺(tái)發(fā)布。還沒(méi)在windows即其他平臺(tái)上發(fā)布,就被HotSpotVm取代。

  • HotSpot Vm
    1)其實(shí)是由一家小公司開發(fā)的,后臺(tái)被sun公司收購(gòu)了。
  • 2)繼承了1.2款虛擬機(jī)的優(yōu)點(diǎn)外,它還增加了熱點(diǎn)代碼探測(cè)技術(shù)等其他

    3)應(yīng)用最多!

  • KVM
    1)kilobyte簡(jiǎn)單,輕量,高度可移植
  • 2)在手機(jī)平臺(tái)運(yùn)行(嵌入式領(lǐng)域)

    5.JRockit
    1)1-4都是sun公司的虛擬機(jī),而JRockit是BEA公司研發(fā)的。不過(guò)在08年被Oracle收購(gòu),后來(lái)sun公司也被Oracle公司收購(gòu)了。

    2)世界上最快的java虛擬機(jī)。

    3)專注服務(wù)器端應(yīng)用。

    4)優(yōu)勢(shì):垃圾收集器;MissionControl服務(wù)套件

    6.J9
    1)IBM公司研發(fā)了。它最開始的名字不叫J9,叫IBM Technology for Java virtual Machine ----IT4j

    2)類似于HotSpot,他不僅可以用于服務(wù)器端,還可以用于桌面應(yīng)用,嵌入式;它開發(fā)是為了IBM產(chǎn)品的各種java平臺(tái)

    7.Dalvik
    1)它不是java虛擬機(jī),因?yàn)樗鼪](méi)有遵循java虛擬機(jī)的規(guī)范,它是不能直接執(zhí)行編譯后的class文件的

    2)它使用的是寄存器架構(gòu),而不是常用的棧架構(gòu)。

    3)它所執(zhí)行的是Dex—dalvik Executalbe文件,這個(gè)文件可以通過(guò)class文件轉(zhuǎn)化而來(lái)。

    4)用于移動(dòng)端----安卓

    8.Microsoft JVM
    1)一看就知道是微軟開發(fā)的,也是為了自家軟件與java兼容

    2)后來(lái)被sun公司搞了,現(xiàn)在沒(méi)了。。。。。

    9.Azul VM 和 Liquid VM(兩款高性能JVM,碾壓HotSpot)
    1)像LiquidVM不需要操作系統(tǒng)的支持,它本身就是一個(gè)操作系統(tǒng)。我們總是說(shuō)java慢,是因?yàn)檫\(yùn)行java代碼時(shí),我們要先進(jìn)過(guò)java虛擬機(jī),再通過(guò)虛擬機(jī)調(diào)操作系統(tǒng),多了一步。

    10.TaobaoVM
    1)淘寶根據(jù)Hotspot進(jìn)行深度定制的的虛擬機(jī)

    2)對(duì)硬件的依賴性夠,犧牲了兼容性。

    4. 為什么叫java 虛擬機(jī),它與 vmware的區(qū)別?

    Java虛擬機(jī)”(縮寫為JVM)是一個(gè)虛構(gòu)出來(lái)的計(jì)算機(jī),是通過(guò)在實(shí)際的計(jì)算機(jī)上仿真模擬各種計(jì)算機(jī)功能來(lái)實(shí)現(xiàn)的。它有自己完善的硬件架構(gòu)(如處理器、堆棧、寄存器等),還具有相應(yīng)的指令系統(tǒng)。使用“Java虛擬機(jī)”程序就是為了支持與操作系統(tǒng)無(wú)關(guān)、在任何系統(tǒng)中都可以運(yùn)行的程序。微軟公司出于競(jìng)爭(zhēng)策略考慮,在Windows XP中不捆綁JVM,所以只能上網(wǎng)下載。

    VM(Virtual Manufacturing ) 主機(jī)其實(shí)就是VMware主機(jī)的簡(jiǎn)稱。VM 虛擬制造:其本質(zhì)是以新產(chǎn)品及其制造系統(tǒng)的全局最優(yōu)化為目標(biāo),以計(jì)算機(jī)支持的仿真技術(shù)為前提,對(duì)設(shè)計(jì)、制造等生產(chǎn)過(guò)程進(jìn)行統(tǒng)一建模,在產(chǎn)品設(shè)計(jì)階段,實(shí)時(shí)地、并行地模擬出產(chǎn)品未來(lái)制造全過(guò)程及其對(duì)產(chǎn)品設(shè)計(jì)的影響,預(yù)測(cè)產(chǎn)品性能、產(chǎn)品制造成本、產(chǎn)品的可行制造等。

    5、java虛擬機(jī)的整體架構(gòu)

    ?JVM(虛擬機(jī)):指以軟件的方式模擬具有完整硬件系統(tǒng)功能、運(yùn)行在一個(gè)完全隔離環(huán)境中的完整計(jì)算機(jī)系統(tǒng) ,是物理機(jī)的軟件實(shí)現(xiàn)。常用的虛擬機(jī)有VMWare,Virtual Box,Java Virtual Machine

    ?Java虛擬機(jī)陣營(yíng):Sun HotSpot VM、BEA JRockit VM、IBM J9 VM、Azul VM、Apache Harmony、Google Dalvik VM、Microsoft JVM…

    6. 字節(jié)碼的加載流程?

    ?JVM由三個(gè)主要的子系統(tǒng)構(gòu)成

    ?類加載器子系統(tǒng)

    ?運(yùn)行時(shí)數(shù)據(jù)區(qū)(內(nèi)存結(jié)構(gòu))

    ?執(zhí)行引擎

    ?Java運(yùn)行時(shí)編譯源碼(.java)成字節(jié)碼,由jre運(yùn)行。jre由java虛擬機(jī)(jvm)實(shí)現(xiàn)。Jvm分析字節(jié)碼,后解釋并執(zhí)行

    .類加載器

  • 負(fù)責(zé)從文件系統(tǒng)(簡(jiǎn)單說(shuō)就是硬盤)或者網(wǎng)絡(luò)上加載class文件,class文 件在文件開頭有特點(diǎn)的標(biāo)識(shí)。

  • ClassLoader只負(fù)責(zé)class文件的加載,只要是符合JVM對(duì)字節(jié)碼文件規(guī)范的要求就可以,至于它是否可以運(yùn)行,由執(zhí)行引擎決定。

  • 加載的類信息存放在方法區(qū)(一塊內(nèi)存空間),除了類信息之外,方法區(qū)中還會(huì)存放運(yùn)行時(shí)常量池信息,可能還會(huì)包括字符串字面量和數(shù)字常量(這部分常量信息是class文件中常量池部分的內(nèi)存映射)

    例如一個(gè)磁盤上的xxx.class文件,會(huì)被JVM的ClassLoader(有很多類加載器)通過(guò)二進(jìn)制流的方式,加載到JVM中,此時(shí)會(huì)生成對(duì)應(yīng)的xxx的class對(duì)象,通過(guò)該class對(duì)象就可以調(diào)用構(gòu)造函數(shù)生成xxx的對(duì)象放在方法區(qū)當(dāng)中。

  • 類加載器加載字節(jié)碼文件主要分為三個(gè)階段:

    加載字節(jié)碼文件

    通過(guò)一個(gè)類的路徑,加載此class文件的二進(jìn)制字節(jié)流將這個(gè)字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)換為方法區(qū)(方法區(qū)具體來(lái)說(shuō),jdk7之前叫永久代,之后叫元數(shù)據(jù)或者元空間,泛稱為方法區(qū))的運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)
    在內(nèi)存中生成一個(gè)代表這個(gè)類的java.lang.class對(duì)象,作為方法區(qū)這個(gè)類各種數(shù)據(jù)的訪問(wèn)入口
    加載字節(jié)碼文件的方式:
    從系統(tǒng)磁盤直接讀取
    通過(guò)網(wǎng)絡(luò)獲取,如:Web Applet(我沒(méi)有了解過(guò)~~~)

    從zip壓縮包中讀取,典型的就是jar包和war包,這些壓縮包中都是已經(jīng)編譯好的字節(jié)碼文件
    運(yùn)行時(shí)生成,如:動(dòng)態(tài)代理(java.lang.reflect)
    其他文件生成,典型的形式如:JSP
    從專用的數(shù)據(jù)庫(kù)中提取class字節(jié)碼文件(我沒(méi)有了解過(guò)~~~)

    鏈接 驗(yàn)證

    確保加載的class字節(jié)碼文件內(nèi)容信息是符合當(dāng)前JVM規(guī)范的,保證被加載類的正確性,不會(huì)有安全風(fēng)險(xiǎn)
    包括文件格式驗(yàn)證、元數(shù)據(jù)驗(yàn)證、字節(jié)碼驗(yàn)證、符號(hào)引用驗(yàn)證(了解一下就好,如校驗(yàn)二進(jìn)制文件頭是否是:CA FE BA BE,CA FE BA BE是JAVA虛擬機(jī)識(shí)別的標(biāo)識(shí)符)

    準(zhǔn)備

    為類變量分配內(nèi)存,并且設(shè)置變量的初始值(0、false或者null等)
    //在鏈接階段的準(zhǔn)備過(guò)程中,a會(huì)被賦值為0,1的賦值會(huì)在初始化階段中進(jìn)行

    int a = 1;

    這里不包含final修飾的static(也就是常量),因?yàn)閒inal修飾的常量在編譯的時(shí)候就會(huì)分配值了,準(zhǔn)備階段會(huì)顯式的初始化
    不會(huì)為實(shí)例變量初始化(未被static修飾的)成員變量,類變量會(huì)被分配到方法區(qū)中,實(shí)例變量隨對(duì)象創(chuàng)建后分配到JVM的堆中

    解析

    將常量池中的符號(hào)引用轉(zhuǎn)換為直接引用的過(guò)程
    符號(hào)引用就是使用符號(hào)來(lái)描述所引用的目標(biāo)(符號(hào)引用的字面量形式定義在《Java虛擬機(jī)規(guī)范》中的class文件格式,可以理解為一個(gè)符號(hào)從字面上定義了引用的目標(biāo)),直接引用就是直接指向目標(biāo)的指針、相對(duì)偏移量、或者一個(gè)間接定位到的目標(biāo)句柄
    解析的目標(biāo)主要針對(duì):類、接口、字段、類方法、接口方法、方法類型等。對(duì)應(yīng)常量池當(dāng)中的CONSTANT_Class_info,CONSTANT_Fieldref_info,CONSTANT_Methodred_info。(這一塊不是很懂)

    初始化

    初始化階段就是執(zhí)行類構(gòu)造方法()的過(guò)程
    構(gòu)造器方法()中的指令,按照源文件中代碼出現(xiàn)的順序執(zhí)行(其實(shí)java的IDE會(huì)有相應(yīng)的語(yǔ)法檢查的,不會(huì)讓你在static靜態(tài)代碼塊中調(diào)用靜態(tài)代碼塊之后聲明的變量的)
    該方法是定義好的,不是類的構(gòu)造方法,構(gòu)造方法對(duì)應(yīng)的class文件中()方法,是javac編譯器自動(dòng)收集類中的所有類變量的賦值動(dòng)作和靜態(tài)代碼塊中的語(yǔ)句合并而來(lái)(簡(jiǎn)單的理解就是()是在編譯的時(shí)候根據(jù)類變量賦值操作代碼和類靜態(tài)代碼塊中的代碼拼接出來(lái)的方法,如果類中沒(méi)有定義靜態(tài)變量或者是靜態(tài)代碼塊那么就不會(huì)有()方法產(chǎn)生)

    七、 java的編譯器輸入的指令流是一種基于棧的指令集架構(gòu), 它有什么優(yōu)點(diǎn)?

    主要特點(diǎn):

    設(shè)計(jì)實(shí)現(xiàn)簡(jiǎn)單,適用于資源受限的系統(tǒng),比如機(jī)頂盒,小玩具上。
    避開寄存器分配難題:使用零地址指令方式分配。
    指令流中大部分都是零地址指令,執(zhí)行過(guò)程依賴操作棧,指令集更小(零地址),編譯器容易實(shí)現(xiàn)。
    不需要硬件支持,可移植性強(qiáng),容易實(shí)現(xiàn)跨平臺(tái)。

    八、能運(yùn)行在虛擬機(jī)上的字節(jié)碼只能由 javac 編譯而來(lái)的java源代碼產(chǎn)生嗎, 除此之外,還有其它哪些語(yǔ)言也可以編譯字節(jié)碼出來(lái)?

    編譯型語(yǔ)言

    編譯型語(yǔ)言,在程序執(zhí)行之前,需要一個(gè)專門的編譯鏈接過(guò)程,把程序編譯成機(jī)器語(yǔ)言文件;比如,exe文件和bin文件。以后運(yùn)行的話就不用重新編譯了,直接使用編譯的結(jié)果就行了。因?yàn)榉g只做了一次,運(yùn)行時(shí)不需要翻譯,所以編譯型語(yǔ)言的程序執(zhí)行效率高!
    ??常見的編譯型語(yǔ)言有:C、C++、Pascal、Object Pascal和Delphi等。

    九、 能簡(jiǎn)單的說(shuō)說(shuō)java虛擬機(jī)規(guī)范嗎?

    ========================================================

    Part Two 類加載相關(guān)

    1. jvm在什么情況下會(huì)加載一個(gè)類?

    類加載過(guò)程
    加載——> 驗(yàn)證 —>準(zhǔn)備—> 解析—> 初始化—> 使用—> 卸載

    在使用的時(shí)候會(huì)加載這個(gè)類

    public class Hello(){public static void mian (){} }

    解析

    解析階段就是把符號(hào)引用轉(zhuǎn)換直接引用

    初始化

    什么是類初始化?

    new getstatic putstatic invokestatic字節(jié)指令
    反射調(diào)用該類
    初始化一個(gè)類會(huì)連帶把父類初始化
    執(zhí)行main方法的類
    使用jdk動(dòng)態(tài)語(yǔ)言支持

    2. 類加載到j(luò)vm中的過(guò)程?每個(gè)階段的工作?

    3. jvm中的類加載器的類型及它加載的目標(biāo)路徑?如何自定義一個(gè)類加載器加載一個(gè)指定目錄下的class文件?

    1、類加載器

    站在Java虛擬機(jī)的角度看,只有兩種不同的類加載器:一種是啟動(dòng)類加載器(Bootstrap ClassLoader),這個(gè)類加載器使用C++語(yǔ)言實(shí)現(xiàn)(HotSpot虛擬機(jī)、JDK8中),是虛擬機(jī)自身的一部分;另外一種是其他所有類加載器,這些類加載器都由Java語(yǔ)言實(shí)現(xiàn),獨(dú)立存在于虛擬機(jī)外部,并且全部繼承自抽象類 java.lang.ClassLoader

    JDK8及以前版本中絕大多數(shù)程序都會(huì)使用到以下3個(gè)系統(tǒng)提供的類加載器來(lái)進(jìn)行加載

    啟動(dòng)類(引導(dǎo)類)加載器

    負(fù)責(zé)加載支撐JVM運(yùn)行的位于<JAVA_HOME>\lib目錄下的核心類庫(kù),而且是Java虛擬機(jī)能夠識(shí)別的類庫(kù)加載到虛擬機(jī)內(nèi)存中(如rt.jar、tools.jar、charsets.jar等,名字不符合的類庫(kù)即使放到lib目錄下也不會(huì)被加載)。
    1.引導(dǎo)類加載器使用C/C++語(yǔ)言實(shí)現(xiàn),在JVM內(nèi)部
    2.用于加載Java核心類庫(kù)
    3.不繼承ClassLoader
    4.還用于加載擴(kuò)展類加載器和應(yīng)用程序類加載器
    5.只加載包名為java,javax,sun開頭的類

    擴(kuò)展類加載器(Extension Class Loader)

    這個(gè)類加載器是在類sun.misc. $ExtClassLoader中以Java代碼的形式實(shí)現(xiàn)的。負(fù)責(zé)加載<JAVA_HOME>\lib\ext目錄中或被java.ext.dirs系統(tǒng)變量所制定的路徑中所有的類庫(kù),是一種Java系統(tǒng)類庫(kù)的擴(kuò)展機(jī)制
    1.使用java語(yǔ)言編寫,JVM自帶
    2.繼承自ClassLoader
    3.父類加載器為啟動(dòng)類加載器
    4.從java.ext.dirs指定的路徑下加載類庫(kù);或者從JDK安裝目錄的jre/lib/ext目錄下加載類庫(kù)。
    5.如果用戶自定義的jar包放在jre/lib/ext下,也會(huì)自動(dòng)由擴(kuò)展類加載器加載

    應(yīng)用程序類加載器(Application Class Loader)

    是由sun.misc.launcher$AppClassLoader來(lái)實(shí)現(xiàn),由于應(yīng)用程序加載器是ClassLoader類中g(shù)etSystemClassLoader()方法的返回值,也稱為系統(tǒng)類加載器。負(fù)責(zé)加載用戶類路徑(ClassPath)上所有的類庫(kù),如應(yīng)用程序中沒(méi)有默認(rèn)自己的類加載器,則使用應(yīng)用程序加載器為默認(rèn)加載器。

    自定義加載器:負(fù)責(zé)加載用戶自定義路徑下的類包
    1.使用jaca語(yǔ)言編寫,JVM自帶
    2.繼承自ClassLoader
    3.父類加載器為擴(kuò)展類加載器
    4.負(fù)責(zé)加載環(huán)境變量classpath或系統(tǒng)屬性java.class.path指定的類庫(kù)
    5.java中自己寫的類都是由應(yīng)用程序類加載器加載的
    6.可以通過(guò)ClassLoader.getSystemClassLoader()方法獲取該類加載器

    理解BootstrapClassLoader、ExtClassLoader、AppClassLoader的例子:

    public class ClassLoaderTest1 {public static void main(String[] args) {System.out.println("**********啟動(dòng)類加載器**************");//獲取BootstrapClassLoader能夠加載的api的路徑URL[] urLs = sun.misc.Launcher.getBootstrapClassPath().getURLs();//獲取到的是通過(guò)引導(dǎo)類加載的類庫(kù)的路徑(輸出參考“引導(dǎo)類能夠加載的類庫(kù)路徑”)for (URL element : urLs) {System.out.println(element.toExternalForm());}//從上面的路徑中隨意選擇一個(gè)類,來(lái)看看他的類加載器是什么:引導(dǎo)類加載器ClassLoader classLoader = Provider.class.getClassLoader();System.out.println(classLoader); //輸出為null。說(shuō)明是引導(dǎo)類加載器加載的System.out.println("***********擴(kuò)展類加載器*************");String extDirs = System.getProperty("java.ext.dirs");for (String path : extDirs.split(";")) {// 輸出參考“擴(kuò)展類能夠加載的類庫(kù)路徑”圖System.out.println(path);}//從上面的路徑中隨意選擇一個(gè)類,來(lái)看看他的類加載器是什么:擴(kuò)展類加載器ClassLoader classLoader1 = CurveDB.class.getClassLoader();System.out.println(classLoader1);//sun.misc.Launcher$ExtClassLoader@1540e19d} }

    自定義一個(gè)類加載器簡(jiǎn)單的例子:

    public class CustomClassLoader extends ClassLoader { //繼承ClassLoader@Overrideprotected Class<?> findClass(String name) throws ClassNotFoundException { //重載findClass方法try {byte[] result = getClassFromCustomPath(name);if(result == null){throw new FileNotFoundException();}else{return defineClass(name,result,0,result.length);}} catch (FileNotFoundException e) {e.printStackTrace();}throw new ClassNotFoundException(name);}private byte[] getClassFromCustomPath(String name){//從自定義路徑中加載指定類:細(xì)節(jié)略//如果指定路徑的字節(jié)碼文件進(jìn)行了加密,則需要在此方法中進(jìn)行解密操作。(這里可以進(jìn)行解密操作,防止class文件被反編譯)return null;}public static void main(String[] args) {CustomClassLoader customClassLoader = new CustomClassLoader();try {Class<?> clazz = Class.forName("One",true,customClassLoader);Object obj = clazz.newInstance();System.out.println(obj.getClass().getClassLoader());} catch (Exception e) {e.printStackTrace();}} }

    4. 什么是雙親委派模型,有什么作用?

    雙親委派模型有兩個(gè)好處:

    向上委托給父類加載,父類加載不了再自己加載
    避免重復(fù)加載,防止Java核心api被篡改
    加載器自上而下分別為,啟動(dòng)類加載器(Bootstrap ClassLoader), 拓展類加載器(Extension ClassLoader), 系統(tǒng)類加載器(Application ClassLoader) , 自定義類加載器(Custom ClassLoader)

    雙親委派模式是Java1.2之后引入的,其工作原理是,如果其中一個(gè)類加載器收到了類加載的請(qǐng)求,它并不會(huì)自己去加載而是會(huì)將該請(qǐng)求委托給父類的加載器去執(zhí)行,如果父類加載器還存在父類加載器,則進(jìn)一步向上委托,如此遞歸,請(qǐng)求最終到達(dá)頂層的啟動(dòng)類加載器。如果父類能加載,則直接返回,如果父類加載不了則交由子類加載,這就是雙親委派模式。

    5. 類加載器是如何確定一個(gè)類在jvm中的唯一性的? 兩個(gè)類來(lái)源于同一個(gè)Class文件,被同一個(gè)虛擬機(jī)加載,這兩個(gè)類一定相等嗎?

    最近遇到了一個(gè)問(wèn)題:由不同類加載器加載同一個(gè)類,實(shí)例化為對(duì)象。使用instanceof判斷該對(duì)象與該類的歸屬,請(qǐng)問(wèn)結(jié)果是true還是false? 答案是false。

    public class ClassLoaderTest {public static void main(String[] args) throws Exception {ClassLoader myLoader = new ClassLoader() {@SuppressWarnings("ResultOfMethodCallIgnored")@Overridepublic Class<?> loadClass(String name) throws ClassNotFoundException {try {String fileName = name.substring(name.lastIndexOf(".") + 1) + ".class";InputStream is = getClass().getResourceAsStream(fileName);if (is == null) {return super.loadClass(name);}byte[] b = new byte[is.available()];is.read(b);return defineClass(name, b, 0, b.length);} catch (IOException e) {throw new ClassNotFoundException(name);}}};Object obj = myLoader.loadClass("jvm.ClassLoaderTest").newInstance();System.out.println(obj.getClass());System.out.println(obj instanceof jvm.ClassLoaderTest);} }

    對(duì)于任意一個(gè)類,都需要由加載它的類加載器和這個(gè)類本身一同確立其在Java虛擬機(jī)中的唯一性,每一個(gè)類加載器,都擁有一個(gè)獨(dú)立的類名稱空間。這句話可以表達(dá)得更通俗一些:比較兩個(gè)類是否“相等”,只有在這兩個(gè)類是由同一個(gè)類加載器加載的前提下才有意義,否則,即使這兩個(gè)類來(lái)源于同一個(gè)Class文件,被同一個(gè)虛擬機(jī)加載,只要加載它們的類加載器不同,那這兩個(gè)類就必定不相等。
    兩行輸出結(jié)果中,從第一句可以看出,這個(gè)對(duì)象確實(shí)是類 Practice.Java.ClassLoaderTest實(shí)例化出來(lái)的對(duì)象,但從第二句可以發(fā)現(xiàn),這個(gè)對(duì)象與類Practice.Java.ClassLoaderTest做所屬類型檢查的時(shí)候卻返回了false。

    這是因?yàn)樘摂M機(jī)中存在了兩個(gè)ClassLoaderTest類,一個(gè)是由系統(tǒng)應(yīng)用程序類加載器加載的,另外一個(gè)是由我們自定義的類加載器加載的。雖然都來(lái)自同一個(gè)Class文件,但依然是兩個(gè)獨(dú)立的類,做對(duì)象所屬類型檢查時(shí)結(jié)果自然為false。

    結(jié)論

    Java類加載器這種特性可以簡(jiǎn)單的總結(jié)為命名空間。即在 Java 虛擬機(jī)中,類的唯一性是由類加載器實(shí)例以及類的全名一同確定的。即便是同一串字節(jié)流,經(jīng)由不同的類加載器加載,也會(huì)得到兩個(gè)不同的類。**

    6. tomcat的類加載器有哪些?

    Tomcat中的類加載器
    下面的簡(jiǎn)圖是Tomcat9版本的官方文檔給出的Tomcat的類加載器的圖

    1.Bootstrap:是java中的最高加載器,用C語(yǔ)言實(shí)現(xiàn),主要用來(lái)加載JVM啟動(dòng)時(shí)所需 要的核心類,如:$JAVA_HOME/jre/lib/ext
    3.System:會(huì)加載CLASSPATH系統(tǒng)變量所定義路徑的所有類
    4.Common:會(huì)加載Tomcat路徑下的lib文件下的所有類
    5.Webapp1,Webapp2????會(huì)加載APP路徑下項(xiàng)目中的所有的類,一個(gè)項(xiàng)目對(duì)應(yīng)一個(gè)6.WabappClassLoader,這樣就實(shí)現(xiàn)了應(yīng)用之間類的隔離

    這3個(gè)部分,在上面的Java雙親委派模型圖中都有體現(xiàn)。不過(guò)可以看到ExtClassLoader沒(méi)有畫出來(lái),可以理解為是跟bootstrap合并了,都是去JAVA_HOME/jre/lib下面加載類。 那么Tomcat為什么要自定義類加載器呢?

    隔離不同應(yīng)用:部署在同一個(gè)Tomcat中的不同應(yīng)用A和B,例如A用了Spring2.5。B用了Spring3.5,那么這兩個(gè)應(yīng)用如果使用的是同一個(gè)類加載器,那么Web應(yīng)用就會(huì)因?yàn)閖ar包覆蓋而無(wú)法啟動(dòng)。
    靈活性:Web應(yīng)用之間的類加載器相互獨(dú)立,那么就可以根據(jù)修改不同的文件重建不同的類加載器替換原來(lái)的。從而不影響其他應(yīng)用。
    性能:如果在一個(gè)Tomcat部署多個(gè)應(yīng)用,多個(gè)應(yīng)用中都有相同的類庫(kù)依賴。那么可以把這相同的類庫(kù)讓Common類加載器進(jìn)行加載。

    Tomcat自定義了WebAppClassLoader類加載器

    打破了雙親委派的機(jī)制,即如果收到類加載的請(qǐng)求,會(huì)嘗試自己去加載,如果找不到再交給父加載器去加載,目的就是為了優(yōu)先加載Web應(yīng)用自己定義的類。我們知道ClassLoader默認(rèn)的loadClass方法是以雙親委派的模型進(jìn)行加載類的,那么Tomcat既然要打破這個(gè)規(guī)則,就要重寫loadClass方法,我們可以看WebAppClassLoader類中重寫的loadClass方法

    @Override public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {synchronized (getClassLoadingLock(name)) {Class<?> clazz = null;// 1. 從本地緩存中查找是否加載過(guò)此類clazz = findLoadedClass0(name);if (clazz != null) {if (log.isDebugEnabled())log.debug(" Returning class from cache");if (resolve)resolveClass(clazz);return clazz;}// 2. 從AppClassLoader中查找是否加載過(guò)此類clazz = findLoadedClass(name);if (clazz != null) {if (log.isDebugEnabled())log.debug(" Returning class from cache");if (resolve)resolveClass(clazz);return clazz;}String resourceName = binaryNameToPath(name, false);// 3. 嘗試用ExtClassLoader 類加載器加載類,防止Web應(yīng)用覆蓋JRE的核心類ClassLoader javaseLoader = getJavaseClassLoader();boolean tryLoadingFromJavaseLoader;try {URL url;if (securityManager != null) {PrivilegedAction<URL> dp = new PrivilegedJavaseGetResource(resourceName);url = AccessController.doPrivileged(dp);} else {url = javaseLoader.getResource(resourceName);}tryLoadingFromJavaseLoader = (url != null);} catch (Throwable t) {tryLoadingFromJavaseLoader = true;}boolean delegateLoad = delegate || filter(name, true);// 4. 判斷是否設(shè)置了delegate屬性,如果設(shè)置為true那么就按照雙親委派機(jī)制加載類if (delegateLoad) {if (log.isDebugEnabled())log.debug(" Delegating to parent classloader1 " + parent);try {clazz = Class.forName(name, false, parent);if (clazz != null) {if (log.isDebugEnabled())log.debug(" Loading class from parent");if (resolve)resolveClass(clazz);return clazz;}} catch (ClassNotFoundException e) {// Ignore}}// 5. 默認(rèn)是設(shè)置delegate是false的,那么就會(huì)先用WebAppClassLoader進(jìn)行加載if (log.isDebugEnabled())log.debug(" Searching local repositories");try {clazz = findClass(name);if (clazz != null) {if (log.isDebugEnabled())log.debug(" Loading class from local repository");if (resolve)resolveClass(clazz);return clazz;}} catch (ClassNotFoundException e) {// Ignore}// 6. 如果此時(shí)在WebAppClassLoader沒(méi)找到類,那么就委托給AppClassLoader去加載if (!delegateLoad) {if (log.isDebugEnabled())log.debug(" Delegating to parent classloader at end: " + parent);try {clazz = Class.forName(name, false, parent);if (clazz != null) {if (log.isDebugEnabled())log.debug(" Loading class from parent");if (resolve)resolveClass(clazz);return clazz;}} catch (ClassNotFoundException e) {// Ignore}}}throw new ClassNotFoundException(name); }

    Web應(yīng)用默認(rèn)的類加載順序是(打破了雙親委派規(guī)則):
    先從JVM的BootStrapClassLoader中加載。
    加載Web應(yīng)用下/WEB-INF/classes中的類。
    加載Web應(yīng)用下/WEB-INF/lib/.jap中的jar包中的類。
    加載上面定義的System路徑下面的類。
    加載上面定義的Common路徑下面的類。
    如果在配置文件中配置了,那么就是遵循雙親委派規(guī)則,加載順序如下:
    . 先從JVM的BootStrapClassLoader中加載。
    . 加載上面定義的System路徑下面的類。
    . 加載上面定義的Common路徑下面的類。
    . 加載Web應(yīng)用下/WEB-INF/classes中的類。
    . 加載Web應(yīng)用下/WEB-INF/lib/.jap中的jar包中的類

    8. 雙親委派模型最大問(wèn)題:底層的類加載器無(wú)法加載底層的類, 比如如下情況:

    javax.xml.parsers包中定義了xml解析的類接口, Service Provider Interface SPI 位于rt.jar
    即接口在啟動(dòng)ClassLoader中, 而SPI的實(shí)現(xiàn)類,通常是由用戶實(shí)現(xiàn)的, 由AppLoader加載。

    以下是javax.xmlparsers.FactoryFinder中的解決代碼:

    static private Class getProviderClass(String className, ClassLoader cl,boolean doFallback, boolean useBSClsLoader) throws ClassNotFoundException {try {if (cl == null) {if (useBSClsLoader) {return Class.forName(className, true, FactoryFinder.class.getClassLoader());} else {cl = ss.getContextClassLoader(); //獲取上下文加載器if (cl == null) {throw new ClassNotFoundException();}else {return cl.loadClass(className); //使用上下文ClassLoader}}}else {return cl.loadClass(className);}}catch (ClassNotFoundException e1) {if (doFallback) {// Use current class loader - should always be bootstrap CLreturn Class.forName(className, true, FactoryFinder.class.getClassLoader());}

    更多可以參考理解: jdbc的SPI 加載方式. https://blog.csdn.net/syh121/article/details/120274044

    ClassLoader cl = Thread.currentThread().getContextClassLoader(); return ServiceLoader.load(service, cl);

    9. 雙親委派模式是默認(rèn)的模式,但并非必須. 還有以下幾個(gè)例 子,它實(shí)際上是破壞了雙親委派模式的.

    a. Tomcat的WebappClassLoader 就會(huì)先加載自己的Class,找不到再委托parent b. OSGi的ClassLoader形成網(wǎng)狀結(jié)構(gòu),根據(jù)需要自由加載Class

    10. 請(qǐng)完成一個(gè)熱替換的例子,并解釋什么是熱替換?

    jvm中只有主動(dòng)使用類,才會(huì)加載類,那么加載類的七種情況有哪些?

    類加載過(guò)程主要分為三個(gè)步驟:加載、鏈接、初始化,而其中鏈接過(guò)程又分為三個(gè)步驟:驗(yàn)證、準(zhǔn)備、解析,加上卸載、使用兩個(gè)步驟統(tǒng)稱為為類的生命周期。

    加載

    簡(jiǎn)單來(lái)說(shuō),加載指的是把class字節(jié)碼文件從各個(gè)來(lái)源通過(guò)類加載器裝載入內(nèi)存中。

    1、字節(jié)碼來(lái)源
    由于沒(méi)有具體指明需要在哪里獲取class文件,導(dǎo)致字節(jié)碼來(lái)源途徑非常豐富:

    從壓縮包中讀取,如jar、war

    從網(wǎng)絡(luò)中獲取,如Web Applet

    動(dòng)態(tài)生成,如動(dòng)態(tài)代理、CGLIB

    由其他文件生成,如JSP

    從數(shù)據(jù)庫(kù)讀取

    從加密文件中讀取

    2、內(nèi)存儲(chǔ)存

    將靜態(tài)儲(chǔ)存解析成運(yùn)行時(shí)數(shù)據(jù),存放在方法區(qū)

    在堆區(qū)生成該類的Class對(duì)象,作為方法區(qū)這個(gè)類的各種數(shù)據(jù)的訪問(wèn)入口。

    驗(yàn)證

    驗(yàn)證階段主要是為了為了確保Class文件的字節(jié)流中包含的信息符合虛擬機(jī)要求,并且不會(huì)危害虛擬機(jī)。

    而驗(yàn)證主要分為以下四類:

    文件格式驗(yàn)證

    元數(shù)據(jù)驗(yàn)證

    字節(jié)碼驗(yàn)證

    符號(hào)引用驗(yàn)證

    總結(jié)

    以上是生活随笔為你收集整理的初步了解java虚拟机的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 久插视频| 激情专区 | 欧美在线视频第一页 | 午夜肉伦伦影院 | 日韩亚洲国产精品 | 538国产精品视频一区二区 | 不卡欧美 | 成人欧美在线视频 | 中文字幕视频网 | 亚洲午夜久久久久 | 久久久www成人免费毛片 | www.中文字幕 | 国产精品精东影业 | 欧美色狠 | 91高清网站 | 亚洲福利影院 | 亚洲乱码电影 | 91久久国语露脸精品国产高跟 | 欧美综合区 | 日韩欧美高清在线视频 | 羞辱极度绿帽vk | 淫欲av| 超碰97观看 | 爱情岛论坛自拍亚洲品质极速最新章 | 中文日韩av| 青青草成人免费视频 | 四虎永久免费 | 欧美日韩国产大片 | www.久久久久.com | 男女日皮视频 | 日韩视频在线观看免费 | 短视频在线观看 | 国产精品美女网站 | 欧美第一页浮力影院 | 中文字幕精品久久久久人妻红杏1 | 成年人在线播放视频 | 国产成人精品一区二区三 | 天天碰免费视频 | 超碰在线人人草 | 无码精品久久久久久久 | 国产日韩欧美视频 | 欧美黄色一级 | 国产成人无码久久久精品天美传媒 | 日韩一区二区中文字幕 | 日韩一区二区三区在线观看 | 国产无套精品一区二区 | 日本xxxxxⅹxxxx69| 久久久综合久久久 | 视频区小说区图片区 | 亚洲精品欧美 | 国产aⅴ精品一区二区三区久久 | 香蕉视频成人在线观看 | 女同毛片一区二区三区 | 色黄视频在线观看 | 中文字幕无码不卡免费视频 | 色又黄又爽 | 深夜福利av | 天天做天天躁天天躁 | 国产女主播喷水高潮网红在线 | 国产黄a三级三级三级 | 日本精品视频在线播放 | 99久久精品免费看国产免费软件 | 国产视频二区 | 日本不卡一区在线 | 成人午夜免费视频 | 日韩一级在线播放 | 午夜精品视频在线 | 国产精品久久久久久久久久久久午夜片 | 天堂va欧美ⅴa亚洲va一国产 | 日本在线免费视频 | 四虎影院一区 | 欧美三级一级 | www.在线观看网站 | 中文字幕三级视频 | 高清一区二区三区 | 性av免费 | 欧美日韩伊人 | 91成人在线观看喷潮动漫 | 亚洲精品v日韩精品 | 国产一级生活片 | 午夜视频在线观看免费视频 | 国产激情久久久久久熟女老人av | 在线97 | 91手机在线观看 | 欧洲在线观看 | 国产va| 亚洲国产一区在线观看 | 国产一级特黄 | 91艹| 水果派解说av | 中文字幕精品视频在线 | 日韩欧美爱爱 | 免费裸体视频网站 | 一区三区在线 | 999国内精品永久免费视频 | 青青草一区 | 黄色成人影视 | 国产性猛交╳xxx乱大交 | 桃色视频网 |