一夜搞懂 | JVM 類加載機(jī)制

前言

本文已經(jīng)收錄到我的Github個(gè)人博客,歡迎大佬們光臨寒舍:

我的GIthub博客

學(xué)習(xí)導(dǎo)圖

學(xué)習(xí)導(dǎo)圖

一.為什么要學(xué)習(xí)類加載機(jī)制署辉?

今天想跟大家嘮嗑嘮嗑Java的類加載機(jī)制,這是Java的一個(gè)很重要的創(chuàng)新點(diǎn),曾經(jīng)也是Java流行的重要原因之一。

Oracle當(dāng)初引入這個(gè)機(jī)制是為了滿足Java Applet開發(fā)的需求集侯,JVM咬咬牙引入了Java類加載機(jī)制,后來的基于Jvm的動(dòng)態(tài)部署帜消,插件化開發(fā)包括大家熱議的熱修復(fù)棠枉,總之很多后來的技術(shù)都源于在JVM中引入了類加載器。

如今泡挺,類加載機(jī)制也在各個(gè)領(lǐng)域大放異彩辈讶,在面試中,由類加載機(jī)制所衍生出來各類面試題也層出不窮娄猫。

所以贱除,我們要了解下類加載機(jī)制,為工作中或者是面試中實(shí)際的需要打好良好的基礎(chǔ)媳溺。

二.核心知識(shí)點(diǎn)歸納

2.1 概述

Q1:JVM類加載機(jī)制定義

虛擬機(jī)把描述類的數(shù)據(jù)從Class文件加載到內(nèi)存月幌,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)轉(zhuǎn)換解析初始化悬蔽,最終形成可被虛擬機(jī)直接使用的Java類型的過程

Q2:特性

運(yùn)行期類加載扯躺。即在Java語言里面,類型的加載蝎困、連接和初始化過程都是在程序運(yùn)行期完成的缅帘,從而通過犧牲一些性能開銷來換取Java程序的高度靈活性

什么是運(yùn)行期,什么是編譯期难衰?

  • 編譯期是指編譯器將源代碼翻譯機(jī)器能識(shí)別的代碼钦无,Java被編譯為Jvm認(rèn)識(shí)的字節(jié)碼文件
  • 運(yùn)行期則是指Java代碼的運(yùn)行過程

JVM運(yùn)行期動(dòng)態(tài)加載+動(dòng)態(tài)連接->Java的動(dòng)態(tài)擴(kuò)展特性

2.2 類加載的過程

類從被加載到虛擬機(jī)內(nèi)存中開始、到卸載出內(nèi)存為止盖袭,整個(gè)生命周期包括七個(gè)階段:

  • 加載

  • 驗(yàn)證

  • 準(zhǔn)備

  • 解析

  • 初始化

  • 使用

  • 卸載

其中失暂,驗(yàn)證彼宠、準(zhǔn)備、解析這3個(gè)部分統(tǒng)稱為連接弟塞,流程如下圖:

類加載過程

注意:

  • 『加載』->『驗(yàn)證』->『準(zhǔn)備』->『初始化』->『卸載』這五個(gè)階段的順序是確定的凭峡,而『解析』可能為了支持Java的動(dòng)態(tài)綁定會(huì)在『初始化』后才開始
  • 上述階段通常都是互相交叉地混合式進(jìn)行的,比如會(huì)在一個(gè)階段執(zhí)行的過程中調(diào)用决记、激活另外一個(gè)階段

想要了解Java動(dòng)態(tài)綁定和靜態(tài)綁定區(qū)別的話摧冀,可以看下這篇文章:理解靜態(tài)綁定與動(dòng)態(tài)綁定

2.2.1 加載

Q1:任務(wù)

  • 通過類的全限定名來獲取定義此類的二進(jìn)制字節(jié)流。如從ZIP包讀取系宫、從網(wǎng)絡(luò)中獲取索昂、通過運(yùn)行時(shí)計(jì)算生成、由其他文件生成扩借、從數(shù)據(jù)庫中讀取等等途徑......

想要詳細(xì)了解類的全限定名的知識(shí)椒惨,可以看下這篇文章:全限定名、簡(jiǎn)單名稱和描述符是什么東西潮罪?

  • 將該二進(jìn)制字節(jié)流所代表的靜態(tài)存儲(chǔ)結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)運(yùn)行時(shí)數(shù)據(jù)結(jié)構(gòu)康谆,該數(shù)據(jù)存儲(chǔ)數(shù)據(jù)結(jié)構(gòu)由虛擬機(jī)實(shí)現(xiàn)自行定義
  • 在內(nèi)存中生成一個(gè)代表這個(gè)類的java.lang.Class對(duì)象,它將作為程序訪問方法區(qū)中的這些類型數(shù)據(jù)的外部接口

2.2.2 驗(yàn)證

  • 連接階段的第一步嫉到,且工作量在JVM類加載子系統(tǒng)中占了相當(dāng)大的一部分
  • 目的:為了確保Class文件的字節(jié)流中包含的信息符合當(dāng)前虛擬機(jī)的要求沃暗,并且不會(huì)危害虛擬機(jī)自身的安全

由此可見,它能直接決定JVM能否承受惡意代碼的攻擊何恶,因此驗(yàn)證階段很重要孽锥,但由于它對(duì)程序運(yùn)行期沒有影響,并不一定必要导而,可以考慮使用-Xverify:none參數(shù)來關(guān)閉大部分的類驗(yàn)證措施忱叭,以縮短虛擬機(jī)類加載的時(shí)間。

  • 檢驗(yàn)過程包括下面四個(gè)階段:

    A.文件格式驗(yàn)證:

    • 內(nèi)容:驗(yàn)證字節(jié)流是否符合Class文件格式的規(guī)范今艺、以及是否能被當(dāng)前版本的虛擬機(jī)處理

    • 目的:保證輸入的字節(jié)流能正確地解析并存儲(chǔ)于方法區(qū)之內(nèi)韵丑,且格式上符合描述一個(gè)Java類型信息的要求。只有保證二進(jìn)制字節(jié)流通過了該驗(yàn)證后虚缎,它才會(huì)進(jìn)入內(nèi)存的方法區(qū)中進(jìn)行存儲(chǔ)撵彻,所以后續(xù)3個(gè)驗(yàn)證階段全部是基于方法區(qū)而不是字節(jié)流了

    • 例子:

      1. 是否以魔數(shù)0xCAFEBABE開頭

      2. 主次版本號(hào)是否在JVM接受范圍內(nèi)

      3. 索引值是否有指向不存在/不符合類型的常量

        ......

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

    • 內(nèi)容:對(duì)字節(jié)碼描述的信息進(jìn)行語義分析,以保證其描述的信息符合Java語言規(guī)范的要求

    • 目的:對(duì)類的元數(shù)據(jù)信息進(jìn)行語義校驗(yàn)实牡,保證不存在不符合Java語言規(guī)范的元數(shù)據(jù)信息

    • 例子:

      1. 類是否有父類(除了java.lang.Object之外陌僵,所有類都應(yīng)有父類)

      2. 父類是否繼承了不允許被繼承的類(final修飾的類)

      3. 如果該類不是抽象類,是否實(shí)現(xiàn)了其父類或接口中要求實(shí)現(xiàn)的所有方法

        ......

    ? C.字節(jié)碼驗(yàn)證:

    • 是驗(yàn)證過程中最復(fù)雜的一個(gè)階段

    • 內(nèi)容:對(duì)類的方法體進(jìn)行校驗(yàn)分析创坞,保證被校驗(yàn)類的方法在運(yùn)行時(shí)不會(huì)做出危害虛擬機(jī)安全的事件

    • 目的:通過數(shù)據(jù)流和控制流分析碗短,確定程序語義是合法的、符合邏輯的

    • 例子:

      1. 保證任意時(shí)刻操作數(shù)棧的數(shù)據(jù)類型與指令代碼序列都能配合工作题涨,例如不會(huì)出現(xiàn)“在操作數(shù)棧的數(shù)據(jù)類型中放置了int類型的數(shù)據(jù)偎谁,使用時(shí)卻按long類型來載入本地變量表中”

      2. 保證任何跳轉(zhuǎn)指令都不會(huì)跳轉(zhuǎn)到方法體外的字節(jié)碼指令上

        ......

    ? D.符號(hào)引用驗(yàn)證:

    • 內(nèi)容:對(duì)類自身以外(如常量池中的各種符號(hào)引用)的信息進(jìn)行匹配性校驗(yàn)
    • 目的:確保解析動(dòng)作能正常執(zhí)行总滩,如果無法通過符號(hào)引用驗(yàn)證,那么將會(huì)拋出一個(gè)java.lang.IncompatibleClassChangeError異常的子類
    • 注意:該驗(yàn)證發(fā)生在虛擬機(jī)將符號(hào)引用轉(zhuǎn)化為直接引用的時(shí)候巡雨,即『解析』階段

2.2.3 準(zhǔn)備

Q1:任務(wù)

  • 為類變量(靜態(tài)變量)分配內(nèi)存因?yàn)檫@里的變量是由方法區(qū)分配內(nèi)存的闰渔,所以僅包括類變量而不包括實(shí)例變量,后者將會(huì)在對(duì)象實(shí)例化時(shí)隨著對(duì)象一起分配在Java堆中
  • 設(shè)置類變量初始值:通常情況下零值

2.2.4 解析

之前提過铐望,解析階段就是虛擬機(jī)將常量池內(nèi)的符號(hào)引用替換為直接引用的過程

  • 符號(hào)引用:以一組符號(hào)來描述所引用的目標(biāo)
  • 可以是任何形式的字面量冈涧,只要使用時(shí)能無歧義地定位到目標(biāo)即可
  • 與虛擬機(jī)實(shí)現(xiàn)的內(nèi)存布局無關(guān),因?yàn)榉?hào)引用的字面量形式明確定義在Java虛擬機(jī)規(guī)范的Class文件格式中正蛙,所以即使各種虛擬機(jī)實(shí)現(xiàn)的內(nèi)存布局不同督弓,但是能接受符號(hào)引用都是一致的
  • 直接引用:
  • 可以是直接指向目標(biāo)的指針、相對(duì)偏移量或是一個(gè)能間接定位到目標(biāo)的句柄
  • 與虛擬機(jī)實(shí)現(xiàn)的內(nèi)存布局相關(guān)跟畅,同一個(gè)符號(hào)引用在不同虛擬機(jī)實(shí)例上翻譯出來的直接引用一般不同
  • 發(fā)生時(shí)間:JVM會(huì)根據(jù)需要來判斷咽筋,是在類被加載器加載時(shí)就對(duì)常量池中的符號(hào)引用進(jìn)行解析溶推,還是等到一個(gè)符號(hào)引用將要被使用前才去解析
  • 解析動(dòng)作:有七類符號(hào)及其對(duì)應(yīng)在常量池的七種常量類型
  • 類或接口(CONSTANT_Class_info)
  • 字段(CONSTANT_Fieldref_info)
  • 類方法(CONSTANT_Methodref_info)
  • 接口方法(CONSTANT_InterfaceMethodref_info)
  • 方法類型(CONSTANT_MethodType_info)
  • 方法句柄(CONSTANT_MethodHandle_info)
  • 調(diào)用點(diǎn)限定符(CONSTANT_InvokeDynamic_info)

舉個(gè)例子徊件,設(shè)當(dāng)前代碼所處的為類D,把一個(gè)從未解析過的符號(hào)引用N解析為一個(gè)類或接口C的直接引用蒜危,解析過程分三步:

  • C不是數(shù)組類型:JVM將會(huì)把代表N的全限定名傳遞給D類加載器去加載這個(gè)類C虱痕。在加載過程中,由于元數(shù)據(jù)驗(yàn)證辐赞、字節(jié)碼驗(yàn)證的需要部翘,又可能觸發(fā)其他相關(guān)類的加載動(dòng)作。一旦這個(gè)加載過程出現(xiàn)了任何異常响委,解析過程就宣告失敗新思。
  • C是數(shù)組類型且數(shù)組元素類型為對(duì)象:JVM也會(huì)按照上述規(guī)則加載數(shù)組元素類型
  • 若上述步驟無任何異常:此時(shí)CJVM中已成為一個(gè)有效的類或接口,但在解析完成前還需進(jìn)行符號(hào)引用驗(yàn)證赘风,來確認(rèn)D是否具備對(duì)C的訪問權(quán)限夹囚。如果發(fā)現(xiàn)不具備訪問權(quán)限,將拋出java.lang.IllegalAccessError異常

Q1:字段(成員變量/域)和屬性有什么區(qū)別邀窃?

  • 屬性荸哟,是指對(duì)象的屬性,對(duì)于JavaBean來說瞬捕,是getXXX方法定義的
  • 字段鞍历,是成員變量
class Person{
    private String mingzi;  //mingzi是字段,一般來說字段和屬性是相同的肪虎,但是這個(gè)例子是特例
    public String getName(){  //name是屬性
        return mingzi:
    }
    public void setName(){
        mingzi= "張三";
    }
}

2.2.5 初始化

  • 是類加載過程的最后一步劣砍,會(huì)開始真正執(zhí)行類中定義的Java代碼。而之前的類加載過程中扇救,除了在『加載』階段用戶應(yīng)用程序可通過自定義類加載器參與之外刑枝,其余階段均由虛擬機(jī)主導(dǎo)和控制
  • 與『準(zhǔn)備』階段的區(qū)分
  • 準(zhǔn)備階段:變量賦初始零值
  • 初始化階段:根據(jù)Java程序的設(shè)定去初始化類變量和其他資源赊淑,或者說是執(zhí)行類構(gòu)造器clinit的過程

clinit:由編譯器自動(dòng)收集類中的所有類變量(靜態(tài)變量)的賦值動(dòng)作和靜態(tài)語句塊static{}中的語句合并產(chǎn)生

  • 線程安全的,在多線程環(huán)境中被正確地加鎖仅讽、同步
  • 對(duì)于類或接口來說是必需的陶缺,如果一個(gè)類中沒有靜態(tài)語句塊,也沒有對(duì)變量的賦值操作洁灵,那么編譯器可以不為這個(gè)類生成 clinit
  • 接口與類不同的是饱岸,執(zhí)行接口的 clinit不需要先執(zhí)行父接口clinit,只有當(dāng)父接口中定義的變量使用時(shí)徽千,父接口才會(huì)初始化苫费。另外,接口的實(shí)現(xiàn)類在初始化時(shí)也一樣不會(huì)執(zhí)行接口的clinit

想詳細(xì)了解clinit以及其與init的區(qū)別的讀者双抽,可以看下這篇文章:深入理解jvm--Java中init和clinit區(qū)別完全解析

  • 在虛擬機(jī)規(guī)范中百框,規(guī)定了有且只有五種情況必須立即對(duì)類進(jìn)行『初始化』:
  • 遇到newgetstatic牍汹、putstaticinvokestatic這4條字節(jié)碼指令時(shí)
  • 使用java.lang.reflect包的方法對(duì)類進(jìn)行反射調(diào)用的時(shí)候
  • 當(dāng)初始化一個(gè)類的時(shí)候铐维,若發(fā)現(xiàn)其父類還未進(jìn)行初始化,需先觸發(fā)其父類的初始化
  • 在虛擬機(jī)啟動(dòng)時(shí)慎菲,需指定一個(gè)要執(zhí)行的主類嫁蛇,虛擬機(jī)會(huì)先初始化它
  • 當(dāng)使用JDK1.7的動(dòng)態(tài)語言支持時(shí),若一個(gè)java.lang.invoke.MethodHandle實(shí)例最后的解析結(jié)果為REF_getStatic露该、REF_putStatic睬棚、REF_invokeStatic的方法句柄,且這個(gè)方法句柄所對(duì)應(yīng)的類未進(jìn)行初始化解幼,需先觸發(fā)其初始化抑党。

2.3 類加載器&雙親委派模型

每個(gè)類加載器,都擁有一個(gè)獨(dú)立的命名空間撵摆,它不僅用于加載類底靠,還和這個(gè)類本身一起作為在JVM中的唯一標(biāo)識(shí)。所以比較兩個(gè)類是否相等台汇,只要看它們是否由同一個(gè)類加載器加載苛骨,即使它們來源于同一個(gè)Class文件且被同一個(gè)JVM加載,只要加載它們的類加載器不同苟呐,這兩個(gè)類就必定不相等

2.3.1 類加載器

JVM的角度痒芝,可將類加載器分為兩種:

  • 啟動(dòng)類加載器
  • C++語言實(shí)現(xiàn),是虛擬機(jī)自身的一部分
  • 負(fù)責(zé)加載存放在<JAVA_HOME>\lib目錄中牵素、或被-Xbootclasspath參數(shù)所指定路徑中的严衬、且可被虛擬機(jī)識(shí)別的類庫
  • 無法被Java程序直接引用,如果自定義類加載器想要把加載請(qǐng)求委派給引導(dǎo)類加載器的話笆呆,可直接用null代替
  • 其他類加載器:由Java語言實(shí)現(xiàn)请琳,獨(dú)立于虛擬機(jī)外部粱挡,并且全都繼承自抽象類java.lang.ClassLoader,可被Java程序直接引用俄精。常見幾種:
  • 擴(kuò)展類加載器

    A.由sun.misc.Launcher$ExtClassLoader實(shí)現(xiàn)

    B.負(fù)責(zé)加載<JAVA_HOME>\lib\ext目錄中的询筏、或者被java.ext.dirs系統(tǒng)變量所指定的路徑中的所有類庫

  • 應(yīng)用程序類加載器

    A.是默認(rèn)的類加載器,是ClassLoader#getSystemClassLoader()的返回值竖慧,故又稱為系統(tǒng)類加載器

    B.由sun.misc.Launcher$App-ClassLoader實(shí)現(xiàn)

    C.負(fù)責(zé)加載用戶類路徑上所指定的類庫

  • 自定義類加載器:如果以上類加載起不能滿足需求嫌套,可自定義

類加載器的關(guān)系

需要注意的是:雖然數(shù)組類不通過類加載器創(chuàng)建而是由JVM直接創(chuàng)建的,但仍與類加載器有密切關(guān)系圾旨,因?yàn)?strong>數(shù)組類的元素類型最終還要靠類加載器去創(chuàng)建

2.3.2 雙親委派模型

  • 定義:表示類加載器之間的層次關(guān)系
  • 前提:除了頂層啟動(dòng)類加載器外踱讨,其余類加載器都應(yīng)當(dāng)有自己的父類加載器,且它們之間關(guān)系一般不會(huì)以繼承關(guān)系來實(shí)現(xiàn)砍的,而是通過組合關(guān)系來復(fù)用父加載器的代碼
  • 工作過程:若一個(gè)類加載器收到了類加載的請(qǐng)求痹筛,它先會(huì)把這個(gè)請(qǐng)求委派給父類加載器,并向上傳遞廓鞠,最終請(qǐng)求都傳送到頂層的啟動(dòng)類加載器中帚稠。只有當(dāng)父加載器反饋?zhàn)约簾o法完成這個(gè)加載請(qǐng)求時(shí),子加載器才會(huì)嘗試自己去加載
  • 注意:不是一個(gè)強(qiáng)制性的約束模型诫惭,而是Java設(shè)計(jì)者推薦給開發(fā)者的一種類加載器實(shí)現(xiàn)方式
  • 優(yōu)點(diǎn):類會(huì)隨著它的類加載器一起具備帶有優(yōu)先級(jí)的層次關(guān)系翁锡,可保證Java程序的穩(wěn)定運(yùn)作蔓挖;實(shí)現(xiàn)簡(jiǎn)單夕土,所有實(shí)現(xiàn)代碼都集中在java.lang.ClassLoader的loadClass()

比如,某些類加載器要加載java.lang.Object類瘟判,最終都會(huì)委派給最頂端的啟動(dòng)類加載器去加載怨绣,這樣Object類在程序的各種類加載器環(huán)境中都是同一個(gè)類。

相反拷获,系統(tǒng)中將會(huì)出現(xiàn)多個(gè)不同的Object類篮撑,Java類型體系中最基礎(chǔ)的行為也就無法保證,應(yīng)用程序也將會(huì)變得一片混亂

三.課堂小測(cè)試

恭喜你匆瓜!已經(jīng)看完了前面的文章赢笨,相信你對(duì)JVM類加載機(jī)制已經(jīng)有一定深度的了解,下面驮吱,進(jìn)行一下課堂小測(cè)試茧妒,驗(yàn)證一下自己的學(xué)習(xí)成果吧!

Q1:類加載的全過程是怎樣的左冬?

Q2:什么是雙親委派模型桐筏?

Q3:String類如何被加載的

上面問題的答案,在前文都提到過拇砰,如果還不能回答出來的話梅忌,建議回顧下前文

Q4:請(qǐng)你談?wù)勵(lì)惣虞d過程狰腌,以Person a = new Person();為例進(jìn)行說明

這道題是在拍恋客的暑假實(shí)習(xí)Tencent一面的面筋上找的琼腔,附上標(biāo)準(zhǔn)答案:類的加載過程,Person person = new Person();為例進(jìn)行說明


如果文章對(duì)您有一點(diǎn)幫助的話踱葛,希望您能點(diǎn)一下贊展姐,您的點(diǎn)贊,是我前進(jìn)的動(dòng)力

本文參考鏈接:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末逊谋,一起剝皮案震驚了整個(gè)濱河市擂达,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌胶滋,老刑警劉巖板鬓,帶你破解...
    沈念sama閱讀 222,729評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異究恤,居然都是意外死亡俭令,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門部宿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來抄腔,“玉大人,你說我怎么就攤上這事理张『丈撸” “怎么了?”我有些...
    開封第一講書人閱讀 169,461評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵雾叭,是天一觀的道長悟耘。 經(jīng)常有香客問我,道長织狐,這世上最難降的妖魔是什么暂幼? 我笑而不...
    開封第一講書人閱讀 60,135評(píng)論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮移迫,結(jié)果婚禮上旺嬉,老公的妹妹穿的比我還像新娘。我一直安慰自己起意,他們只是感情好鹰服,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,130評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般悲酷。 火紅的嫁衣襯著肌膚如雪套菜。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評(píng)論 1 312
  • 那天设易,我揣著相機(jī)與錄音逗柴,去河邊找鬼。 笑死顿肺,一個(gè)胖子當(dāng)著我的面吹牛戏溺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播屠尊,決...
    沈念sama閱讀 41,179評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼旷祸,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了讼昆?” 一聲冷哼從身側(cè)響起托享,我...
    開封第一講書人閱讀 40,124評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎浸赫,沒想到半個(gè)月后闰围,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,657評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡既峡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,723評(píng)論 3 342
  • 正文 我和宋清朗相戀三年羡榴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片运敢。...
    茶點(diǎn)故事閱讀 40,872評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡校仑,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出者冤,到底是詐尸還是另有隱情肤视,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評(píng)論 5 351
  • 正文 年R本政府宣布涉枫,位于F島的核電站,受9級(jí)特大地震影響腐螟,放射性物質(zhì)發(fā)生泄漏愿汰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,213評(píng)論 3 336
  • 文/蒙蒙 一乐纸、第九天 我趴在偏房一處隱蔽的房頂上張望衬廷。 院中可真熱鬧,春花似錦汽绢、人聲如沸吗跋。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽跌宛。三九已至酗宋,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間疆拘,已是汗流浹背蜕猫。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留哎迄,地道東北人回右。 一個(gè)月前我還...
    沈念sama閱讀 49,304評(píng)論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像漱挚,于是被迫代替她去往敵國和親翔烁。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,876評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 代碼編譯的結(jié)果從本地機(jī)器碼轉(zhuǎn)變?yōu)樽止?jié)碼旨涝,是存儲(chǔ)格式發(fā)展的一小步租漂,確實(shí)編譯語言發(fā)展的一大步。 虛擬機(jī)把描述類的數(shù)據(jù)從...
    胡二囧閱讀 961評(píng)論 0 0
  • 虛擬機(jī)把描述類的數(shù)據(jù)從Class文件加載到內(nèi)存颊糜,并對(duì)數(shù)據(jù)進(jìn)行校驗(yàn)哩治、轉(zhuǎn)換解析和初始化,最終形成可以被虛擬機(jī)直接使用的...
    丑人林宗己閱讀 570評(píng)論 0 2
  • 原文地址[http://blog.csdn.net/ns_code/article/details/1788158...
    期待現(xiàn)在閱讀 267評(píng)論 0 2
  • Java虛擬機(jī)整體篇幅如下: Java虛擬機(jī)基礎(chǔ)——1Java的內(nèi)存模型Java虛擬機(jī)基礎(chǔ)——2JVM運(yùn)行時(shí)數(shù)據(jù)區(qū)...
    隔壁老李頭閱讀 2,801評(píng)論 1 16
  • 文/南熠姑梁 在文章開頭衬鱼,引用一段百度百科文字——2016年底以來业筏,國內(nèi)共享單車突然就火爆了起來。在街頭鸟赫,仿佛一夜...
    南熠姑梁閱讀 334評(píng)論 5 4