Java當中JVM 01 在使用控制面板時的實質: 使用 ,然後變成為 通過運行 這個命令,在類載入器中(含有載入,驗證,準備,解析,初始化,使用,卸載),到 為Java虛擬機中運行,在 中有方法區,堆記憶體,線程棧,本地方法棧, 計數器。 類載入器: 1. 載入, 2. 驗證, 文件的版本是否能相容 ...
Java當中JVM
01
在使用控制面板時的實質:
Hello.java
使用javac
,然後變成為Hello.class
通過運行java
這個命令,在類載入器中(含有載入,驗證,準備,解析,初始化,使用,卸載),到jvm
為Java虛擬機中運行,在jvm
中有方法區,堆記憶體,線程棧,本地方法棧,PC
計數器。
類載入器:
- 載入,
- 驗證,
class
文件的版本是否能相容當前的Java
虛擬機版本,然後class
文件要滿足虛擬機的規範。 - 準備,需要準備什麼呢?就是要進行類成員的初始化為初始值,其中為
final
修飾的類變數除外,final
變數就直接初始化為變數值,而類成員不一樣。 - 解析,什麼是解析呢?就是把符號引用解析為直接引用,就是我們變數
xxx
,這種代表變為直接引用,什麼是直接引用呢?就是記憶體地址,如我們常見的xxx0203r0e
,這種。 - 初始化,把關於
static
修飾的變數或者是static
靜態代碼塊按照順序組成構造器進行初始化變數。 - 使用,
- 卸載
JVM
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
中有個堆記憶體,就會申請一片空間記憶體地址,即創建一個對象,實例變數,實例方法從方法區中指向堆記憶體。
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靜態代碼塊進行初始化變數)
步驟:
在堆記憶體中執行的順序就是載入實例信息,然後在進行構造方法。
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)
中。
往後餘生,唯獨有你
簡書作者:達叔小生
90後帥氣小伙,良好的開發習慣;獨立思考的能力;主動並且善於溝通
簡書博客: https://www.jianshu.com/u/c785ece603d1
結語
- 下麵我將繼續對 其他知識 深入講解 ,有興趣可以繼續關註
- 小禮物走一走 or 點贊