2. JVM 初篇

類加載

  • 在Java代碼中,類型的加載框产、連接與初始化過程都是在程序運行期間完成的
  • 提供了更大的靈活性凄杯,增加了更多的可能性

Java虛擬機與程序的生命周期

jvm.PNG

在如下幾種情況下,Java虛擬機將結(jié)束生命周期

  • 執(zhí)行了System.exit()方法
  • 程序正常執(zhí)行結(jié)束
  • 程序在執(zhí)行過程中遇到了異趁┬牛或錯誤而異常終止
  • 由于操作系統(tǒng)出現(xiàn)錯誤而導致Java虛擬機進程終止

類的加載盾舌、連接與初始化

  • 加載:查找并加載類的二進制數(shù)據(jù)
  • 連接
    • 驗證:確保被加載的類的正確性
    • 準備:為類的靜態(tài)變量分配內(nèi)存,并將其初始化為默認值
    • 解析:把類中的符號引用轉(zhuǎn)換為直接引用
  • 初始化:為類的靜態(tài)變量賦予正確的初始值
class Test {
  public static int a = 1; // 準備階段a的值為0
}

類的使用與卸載

  • 使用
  • 卸載

Java程序?qū)︻惖氖褂梅绞娇煞譃閮煞N

  • 主動使用
  • 被動使用

所有的Java虛擬機實現(xiàn)必須在每個類或接口被Java程序“首次主動使用”時才初始化他們

主動使用(七種)

  • 創(chuàng)建類的實例
  • 訪問某個類或接口的靜態(tài)變量蘸鲸,或者對該靜態(tài)變量賦值
  • 調(diào)用類的靜態(tài)方法
  • 反射(如Class.forName("com.test.Test"))
  • 初始化一個類的子類
  • Java虛擬機啟動時被標明為啟動類的類(Java Test)
  • JDK1.7開始提供的動態(tài)語言支持: java.lang.invoke.MethodHandle實例的解析結(jié)果REF_getStatic, REF_putStatic,REF_invokeStatic句柄對應的類沒有初始化則初始化

助記符

  • getStatic
  • putStatic
  • invokeStatic

除了以上七種情況妖谴,其他使用Java類的方式都被看作是對類的被動使用,都不會導致類的初始化

類的加載

  • 類的加載指的是將類的.class文件中的二進制數(shù)據(jù)讀入到內(nèi)存中,將其放在運行時數(shù)據(jù)區(qū)的方法區(qū)內(nèi)酌摇,然后在內(nèi)存中創(chuàng)建一個
    java.lang.Class對象(規(guī)范并未說明Class對象位于哪里膝舅,HotSpot虛擬機將其放在了方法區(qū)中)用來封裝類在方法區(qū)的數(shù)據(jù)結(jié)構

  • 加載.class文件的方式

    • 從本地系統(tǒng)中直接加載
    • 通過網(wǎng)絡下載.class文件
    • 從zip,jar等歸檔文件中加載.class文件
    • 從專有數(shù)據(jù)庫中提取.class文件
    • 將Java源文件動態(tài)編譯為.class文件
public class MyTest1 {

  public static void main(String[] args) {

    // 1. 對于靜態(tài)字段來說,只有直接定義了該字段的類才會被初始化
    // 2. 當一個類在初始化時窑多,要求其父類全部都已經(jīng)初始化完畢

    // System.out.println(MyChild1.str);

    System.out.println(MyChild1.str);

    // 發(fā)現(xiàn)加載了MyChild1類仍稀,但未初始化
    // [Loaded com.yhyecho.classload.MyParent1 from file:/C:/MySpace/jvm/target/classes/]
    // [Loaded com.yhyecho.classload.MyChild1 from file:/C:/MySpace/jvm/target/classes/]

    // JVM參數(shù)配置規(guī)則
    // -XX:+TraceClassLoading, 用于追蹤類的加載信息并打印出來

    // -XX:+<option>, 表示開啟option選項
    // -XX:-<option>, 表示關閉option選項
    // -XX:<option>=<value>, 表示將option選項的值設置為value

  }

}

class MyParent1 {

  static String str = "hello world";

  static {
    System.out.println("MyParent1 static block");
  }
}

class MyChild1 extends MyParent1 {

  static String str2 = "welcome";

  static {
    System.out.println("MyChild static block");
  }
}

JVM參數(shù)配置規(guī)則

  • -XX:+TraceClassLoading, 用于追蹤類的加載信息并打印出來
  • -XX:+<option>, 表示開啟option選項
  • -XX:-<option>, 表示關閉option選項
  • -XX:<option>=<value>, 表示將option選項的值設置為value
public class MyTest2 {

  public static void main(String[] args) {

    // 常量在編譯階段會存入到調(diào)用這個常量的方法所在的類的常量池中,
    // 本質(zhì)上,調(diào)用類并沒有直接引用到定義常量的類, 因此并不會觸發(fā)定義常量類的初始化

    // 注意:這里指的是將常量存放在MyTest2的常量池中埂息,之后MyTest2與MyParent2就沒有任何關系了
    // 甚至技潘,我們可以將MyParent2的class文件刪除

    System.out.println(MyParent2.str);

    System.out.println(MyParent2.s);

    System.out.println(MyParent2.i);

    System.out.println(MyParent2.m1);

    System.out.println(MyParent2.m);

    // 使用javap -c MyTest2.class 反編譯字節(jié)碼
    // 驚喜的發(fā)現(xiàn)一些助記符
    // ldc表示將int,float或是String類型的常量值從常量池中推送至棧頂
    // bipush表示將單字節(jié)(-128 ~ 127) 的常量值推送至棧頂
    // sipush表示將一個短整型常量值(-32768 ~ 32767) 推送至棧頂
    // iconst_1表示將int類型1推送至棧頂(iconst_1 ~ iconst_5)
  }
}

class MyParent2 {

  // 1.
  // static String str = "hello world";

  // 2. 常量池
  static final String str = "hello world";

  static final short s = 127;

  static final int i = 128;

  static final int m1 = 1;

  static final int m = 6;

  static {
    System.out.println("MyParent2 static block");
  }

}
public class MyTest3 {

  // 當一個常量的值并非編譯期間可以確定的千康,那么其值就不會被放到調(diào)用類的常量池中享幽,
  // 這時在程序運行時,會導致主動使用這個常量所在的類,顯然會導致這個類的被初始化拾弃。
  public static void main(String[] args) {
    System.out.println(MyParent3.str);
  }
}

class MyParent3 {

  static final String str = UUID.randomUUID().toString();

  static {
    System.out.println("MyParent3 static code");
  }
}
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末值桩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子豪椿,更是在濱河造成了極大的恐慌奔坟,老刑警劉巖携栋,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異咳秉,居然都是意外死亡婉支,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門滴某,熙熙樓的掌柜王于貴愁眉苦臉地迎上來磅摹,“玉大人,你說我怎么就攤上這事霎奢』模” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵幕侠,是天一觀的道長帝美。 經(jīng)常有香客問我,道長晤硕,這世上最難降的妖魔是什么悼潭? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮舞箍,結(jié)果婚禮上舰褪,老公的妹妹穿的比我還像新娘。我一直安慰自己疏橄,他們只是感情好占拍,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著捎迫,像睡著了一般晃酒。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上窄绒,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天贝次,我揣著相機與錄音,去河邊找鬼彰导。 笑死蛔翅,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的位谋。 我是一名探鬼主播山析,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼倔幼!你這毒婦竟也來了盖腿?” 一聲冷哼從身側(cè)響起爽待,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤损同,失蹤者是張志新(化名)和其女友劉穎翩腐,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體膏燃,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡茂卦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了组哩。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡黍衙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出聂抢,到底是詐尸還是另有隱情,我是刑警寧澤轿亮,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布迟隅,位于F島的核電站奔缠,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏腰奋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一灌危、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸盗誊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哈踱。三九已至荒适,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間开镣,已是汗流浹背刀诬。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留邪财,地道東北人陕壹。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像树埠,于是被迫代替她去往敵國和親糠馆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

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