'Java虛擬機原理'

虛擬機 Java Java虛擬機 進擊的IT程序員 2019-08-04
"

文章目錄

  • 代碼的大體執行過程
  • 代碼在JVM裡面的詳細執行過程
  • 類加載器詳解
  • 運行時數據區詳解

先來看下面這一段代碼:

"

文章目錄

  • 代碼的大體執行過程
  • 代碼在JVM裡面的詳細執行過程
  • 類加載器詳解
  • 運行時數據區詳解

先來看下面這一段代碼:

Java虛擬機原理

代碼的大體執行過程

JDK、JRE、JVM的區別和聯繫;

代碼的大體執行過程如下:

"

文章目錄

  • 代碼的大體執行過程
  • 代碼在JVM裡面的詳細執行過程
  • 類加載器詳解
  • 運行時數據區詳解

先來看下面這一段代碼:

Java虛擬機原理

代碼的大體執行過程

JDK、JRE、JVM的區別和聯繫;

代碼的大體執行過程如下:

Java虛擬機原理

從.java源文件編譯生成.class字節碼文件的過程如下:

"

文章目錄

  • 代碼的大體執行過程
  • 代碼在JVM裡面的詳細執行過程
  • 類加載器詳解
  • 運行時數據區詳解

先來看下面這一段代碼:

Java虛擬機原理

代碼的大體執行過程

JDK、JRE、JVM的區別和聯繫;

代碼的大體執行過程如下:

Java虛擬機原理

從.java源文件編譯生成.class字節碼文件的過程如下:

Java虛擬機原理

代碼在JVM裡面的詳細執行過程

在JVM內部就這個樣子的:

"

文章目錄

  • 代碼的大體執行過程
  • 代碼在JVM裡面的詳細執行過程
  • 類加載器詳解
  • 運行時數據區詳解

先來看下面這一段代碼:

Java虛擬機原理

代碼的大體執行過程

JDK、JRE、JVM的區別和聯繫;

代碼的大體執行過程如下:

Java虛擬機原理

從.java源文件編譯生成.class字節碼文件的過程如下:

Java虛擬機原理

代碼在JVM裡面的詳細執行過程

在JVM內部就這個樣子的:

Java虛擬機原理

然後,先說說類裝載子系統

"

文章目錄

  • 代碼的大體執行過程
  • 代碼在JVM裡面的詳細執行過程
  • 類加載器詳解
  • 運行時數據區詳解

先來看下面這一段代碼:

Java虛擬機原理

代碼的大體執行過程

JDK、JRE、JVM的區別和聯繫;

代碼的大體執行過程如下:

Java虛擬機原理

從.java源文件編譯生成.class字節碼文件的過程如下:

Java虛擬機原理

代碼在JVM裡面的詳細執行過程

在JVM內部就這個樣子的:

Java虛擬機原理

然後,先說說類裝載子系統

Java虛擬機原理

然後是運行時數據區(內存模型)的:

"

文章目錄

  • 代碼的大體執行過程
  • 代碼在JVM裡面的詳細執行過程
  • 類加載器詳解
  • 運行時數據區詳解

先來看下面這一段代碼:

Java虛擬機原理

代碼的大體執行過程

JDK、JRE、JVM的區別和聯繫;

代碼的大體執行過程如下:

Java虛擬機原理

從.java源文件編譯生成.class字節碼文件的過程如下:

Java虛擬機原理

代碼在JVM裡面的詳細執行過程

在JVM內部就這個樣子的:

Java虛擬機原理

然後,先說說類裝載子系統

Java虛擬機原理

然後是運行時數據區(內存模型)的:

Java虛擬機原理

最後是執行引擎:

"

文章目錄

  • 代碼的大體執行過程
  • 代碼在JVM裡面的詳細執行過程
  • 類加載器詳解
  • 運行時數據區詳解

先來看下面這一段代碼:

Java虛擬機原理

代碼的大體執行過程

JDK、JRE、JVM的區別和聯繫;

代碼的大體執行過程如下:

Java虛擬機原理

從.java源文件編譯生成.class字節碼文件的過程如下:

Java虛擬機原理

代碼在JVM裡面的詳細執行過程

在JVM內部就這個樣子的:

Java虛擬機原理

然後,先說說類裝載子系統

Java虛擬機原理

然後是運行時數據區(內存模型)的:

Java虛擬機原理

最後是執行引擎:

Java虛擬機原理

類加載器詳解

class文件的加載過程詳細的可以看我的另一篇博客,類加載器;

補充的一點是:

虛擬機規範中明確了在5中情況下會對類進行加載:

創建對象實例:new 對象的時候,會對類進行初始化(前提是這個類沒有被初始化);

通過class文件反射創建對象;

調用類的靜態屬性或靜態屬性賦值;

調用類中的靜態方法;

初始化一個類的子類的時候,在使用子類的時候,先初始化父類;

Java虛擬機啟動時被標記為啟動類的的類,比如main所在的類;

不會被加載的情況:

在同一個虛擬機中,一個類只能被加載一次,如果已經被初始化的一個類不會再被加載;

在編譯時,能確定下來的靜態變量,不會對類進行初始化;

運行時數據區詳解

從上面的運行時數據區(內存模型)的模型圖我們可以看到,堆和方法區是線程之間共享的(會發生併發安全的地方),而虛擬機棧、本地方法棧、程序計數器是線程私有的(也就是每個線程都已自己的虛擬機棧、本地方法棧和程序計數器),下面是關於內存模型中各個部分的介紹:

程序計數器(線程私有):就是一個指針,指向方法區中的方法字節碼(用來存儲下一條指令的地址,也就是馬上要執行的指令的地址),有執行引擎讀取下一條指令,是一個非常小的空間,幾乎可以忽略不計;

方法區(線程共享):類的所有字段和方法字節碼,以及一些特殊方法如:構造函數,接口代碼也在此定義,簡單說,所有定義的方法的信息都保存在該區域,靜態變量+常量+類信息(構造方法/接口定義)+運行時常量池都存在方法區中;

虛擬機棧(線程私有):Java線程執行方法的內存模型,一個線程對應一個棧,每個方法在執行的同時都會創建一個棧幀(用於存儲局部變量表,操作數棧,動態鏈接,方法出口等信息),不存在垃圾回收等問題,只要線程一結束就釋放,生命週期和線程一致;

本地方法棧(線程私有):就是存放哪些native方法的;

堆(線程共享):很大的一塊空間,用於存放對象實例,垃圾回收主要發生的地方;

棧幀中的組成部分介紹:

局部變量表:可以這麼理解,局部變量表裡面存放的是一個一個的小容器,用來存放數據的,比如我們開頭那段代碼中的a = 1, b = 2,在虛擬機裡面不可能真給你弄出一個a、b來存放1和2,於是就用局部變量表中的這些小容器來存放,比如容器1存放1,容器2存放2,容器3存放他們的計算結果300……,當然,除了能存放基本的數據類型以外,還可以存放引用類型的對象指針;

操作數棧:每次要進行操作時(相加、相減、乘除等等),先把相關的數都放到操作數棧裡面,讓後繼續相關的操作,並將操作的結果放到局部變量表中去;

動態鏈接:比如上面那個main方法運行到第二行就要進入到add()方法中去了,就是在運行的時候將符號引用轉化為直接引用;

方法出口:比如上面的代碼,add()方法運行完之後,還要將結果返回給main方法的,這個主要指的是return一類的;

"

文章目錄

  • 代碼的大體執行過程
  • 代碼在JVM裡面的詳細執行過程
  • 類加載器詳解
  • 運行時數據區詳解

先來看下面這一段代碼:

Java虛擬機原理

代碼的大體執行過程

JDK、JRE、JVM的區別和聯繫;

代碼的大體執行過程如下:

Java虛擬機原理

從.java源文件編譯生成.class字節碼文件的過程如下:

Java虛擬機原理

代碼在JVM裡面的詳細執行過程

在JVM內部就這個樣子的:

Java虛擬機原理

然後,先說說類裝載子系統

Java虛擬機原理

然後是運行時數據區(內存模型)的:

Java虛擬機原理

最後是執行引擎:

Java虛擬機原理

類加載器詳解

class文件的加載過程詳細的可以看我的另一篇博客,類加載器;

補充的一點是:

虛擬機規範中明確了在5中情況下會對類進行加載:

創建對象實例:new 對象的時候,會對類進行初始化(前提是這個類沒有被初始化);

通過class文件反射創建對象;

調用類的靜態屬性或靜態屬性賦值;

調用類中的靜態方法;

初始化一個類的子類的時候,在使用子類的時候,先初始化父類;

Java虛擬機啟動時被標記為啟動類的的類,比如main所在的類;

不會被加載的情況:

在同一個虛擬機中,一個類只能被加載一次,如果已經被初始化的一個類不會再被加載;

在編譯時,能確定下來的靜態變量,不會對類進行初始化;

運行時數據區詳解

從上面的運行時數據區(內存模型)的模型圖我們可以看到,堆和方法區是線程之間共享的(會發生併發安全的地方),而虛擬機棧、本地方法棧、程序計數器是線程私有的(也就是每個線程都已自己的虛擬機棧、本地方法棧和程序計數器),下面是關於內存模型中各個部分的介紹:

程序計數器(線程私有):就是一個指針,指向方法區中的方法字節碼(用來存儲下一條指令的地址,也就是馬上要執行的指令的地址),有執行引擎讀取下一條指令,是一個非常小的空間,幾乎可以忽略不計;

方法區(線程共享):類的所有字段和方法字節碼,以及一些特殊方法如:構造函數,接口代碼也在此定義,簡單說,所有定義的方法的信息都保存在該區域,靜態變量+常量+類信息(構造方法/接口定義)+運行時常量池都存在方法區中;

虛擬機棧(線程私有):Java線程執行方法的內存模型,一個線程對應一個棧,每個方法在執行的同時都會創建一個棧幀(用於存儲局部變量表,操作數棧,動態鏈接,方法出口等信息),不存在垃圾回收等問題,只要線程一結束就釋放,生命週期和線程一致;

本地方法棧(線程私有):就是存放哪些native方法的;

堆(線程共享):很大的一塊空間,用於存放對象實例,垃圾回收主要發生的地方;

棧幀中的組成部分介紹:

局部變量表:可以這麼理解,局部變量表裡面存放的是一個一個的小容器,用來存放數據的,比如我們開頭那段代碼中的a = 1, b = 2,在虛擬機裡面不可能真給你弄出一個a、b來存放1和2,於是就用局部變量表中的這些小容器來存放,比如容器1存放1,容器2存放2,容器3存放他們的計算結果300……,當然,除了能存放基本的數據類型以外,還可以存放引用類型的對象指針;

操作數棧:每次要進行操作時(相加、相減、乘除等等),先把相關的數都放到操作數棧裡面,讓後繼續相關的操作,並將操作的結果放到局部變量表中去;

動態鏈接:比如上面那個main方法運行到第二行就要進入到add()方法中去了,就是在運行的時候將符號引用轉化為直接引用;

方法出口:比如上面的代碼,add()方法運行完之後,還要將結果返回給main方法的,這個主要指的是return一類的;

Java虛擬機原理

"

相關推薦

推薦中...