Java當中的JVM

01

在使用控制面板時的實質:java

Hello.java使用javac,而後變成爲Hello.class經過運行java這個命令,在類加載器中(含有加載,驗證,準備,解析,初始化,使用,卸載),到jvm爲Java虛擬機中運行,在jvm中有方法區,堆內存,線程棧,本地方法棧,PC計數器。jvm

Java運行條件

類加載器:測試

  1. 加載,
  2. 驗證,class文件的版本是否能兼容當前的Java虛擬機版本,而後class文件要知足虛擬機的規範。
  3. 準備,須要準備什麼呢?就是要進行類成員的初始化爲初始值,其中爲final修飾的類變量除外,final變量就直接初始化爲變量值,而類成員不同。
  4. 解析,什麼是解析呢?就是把符號引用解析爲直接引用,就是咱們變量xxx,這種表明變爲直接引用,什麼是直接引用呢?就是內存地址,如咱們常見的xxx0203r0e,這種。
  5. 初始化,把關於static修飾的變量或者是static靜態代碼塊按照順序組成構造器進行初始化變量。
  6. 使用,
  7. 卸載

JVMspa

JVM: 方法區(保存全部類的信息,經過常量池來保存生成全部類信息的對象),堆內存,線程棧,本地方法棧,計數器。線程

// 在控制面板中,反編譯
javap -c xxx 
就是將字節碼反編譯爲字節碼的指令輸出
public class Hello{
 public Hello();
  Code:
   0: aload_0
   1: invokespecial #1
   4: return
 public static void main(java.lang.String[]);
  ...
}

把程序放進jvm中運行,到線程棧中運行,主方法main(主線程),在線程棧中運行若是有遇到new對象關鍵字時,main這個主線程就會在本身的內存中(線程棧)聲明一個的對象(對象的引用指向堆內存中開闢的對象),Hello hello;在jvm中有個堆內存,就會申請一片空間內存地址,即建立一個對象,實例變量,實例方法從方法區中指向堆內存。code

public class Hello{
 public static void main(String[] args){
  Hello hello = new Hello();
  // 對象的聲明 和 建立對象
 }
}

類加載到虛擬機中:對象

public class Demo
 static {
  System.out.println("靜態代碼塊");
 }
 {
   System.out.println("普通代碼塊");
  }
  public Demo(){
   System.out.println("構造方法");
 }
  public static void main(String[] args){
   new Demo();
  }
}
// 結果
靜態代碼塊
普通代碼塊
構造方法

// 加載 驗證 準備 解析 初始化 使用 卸載
Demo.java -> Demo.class -> 加載進入虛擬機中,類加載器 (驗證類信息,元素信息,版本,字節碼,準備,初始化類變量,解析把符號引用解析爲直接引用,進行初始化就是把static變量和static靜態代碼塊進行初始化變量)

步驟:blog

在堆內存中執行的順序就是加載實例信息,而後在進行構造方法。繼承

02

瞭解static案例內存

// 父類
public class F
 static {
  System.out.println("F靜態代碼塊");
 }
 {
   System.out.println("F普通代碼塊");
  }
  public F(){
   System.out.println("F構造方法");
 }
}
// 子類
public class S extends F
 static {
  System.out.println("S靜態代碼塊");
 }
 {
   System.out.println("S普通代碼塊");
  }
  public S(){
   super(); // 默認的
   System.out.println("S構造方法");
 }
}
// 測試
public class Demo
  public static void main(String[] args){
  // 建立子類對象
   new S();
  }
}
// 結果
F靜態代碼塊
S靜態代碼塊
F普通代碼塊
F構造方法
S普通代碼塊
S構造方法

程序進入JVM中的方法區,子類繼承父類,父類進行加載實例信息進入到開闢的內存中,而後執行完再執行構造方法,在堆內存中new一個對象,new S(); 在子類的構造方法中會有默認的super(),加載父類,若是子類調用默認調用super(),而父類沒有無參的構造方法,而是有參的構造方法,那麼就要本身添加,在super(xxx)中。

相關文章
相關標籤/搜索