成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

理解了 1+2的過程,就理解了Java虛擬機

云計算 虛擬化
在面試的時候,在問到關于JVM相關的問題,會發現不少的面試者都是機械的在記憶,稍一細問就戛然而止。屬于死記硬背型的,估計是看書里記個大概的概念或者圖,并沒有理解含義。

[[322423]]

在面試的時候,在問到關于JVM相關的問題,會發現不少的面試者都是機械的在記憶,稍一細問就戛然而止。屬于死記硬背型的,估計是看書里記個大概的概念或者圖,并沒有理解含義。

實際上這塊內容,看概念的時候能對照一個簡單的程序分析,可以更好的理解。下面咱們開始。

市面上常見的JVM書籍里,關于JVM的體系結構,一般劃分成以下幾個部分:

  1. 類加載器
  2. 程序計數器(Program Counter Register,簡稱PC Register)
  3. Java 虛擬機棧(Java Virtual Machine Stacks)
  4. 堆(Heap)
  5. 方法區(Method Area)
  6. 運行時常量池(Run-time Constant Pool)
  7. 本地方法棧(Native Method Stack)
  8. 棧幀(Stack Frame)
  9. 執行引擎(Execution Engine)

其中2~7項,又稱為運行時數據區,畢竟這些東西只有JVM 跑起來才會創建。這個分類,基本都是參照 Java 虛擬機規范。

如果干巴巴的記概念沒啥意思,吃個飯可能就忘了。接下來用 1+2這個程序來試著理解它。

我們來看個初學Java 編程的時候都基本都寫過的,類似 Hello World的程序。

  1. public class HelloWorld { 
  2.     public static void main(String[] args) { 
  3.         int a = 1; 
  4.         int b = 2; 
  5.         int c = a + b; 
  6.     } 

先 javac 編譯之后,再用javap -verbose HelloWorld 來觀察一下, 你會看到類似下面的輸出內容:

  1. public class HelloWorld 
  2.   minor version: 0 
  3.   major version: 55 
  4.   flags: (0x0021) ACC_PUBLIC, ACC_SUPER 
  5.   this_class: #2     // HelloWorld 
  6.   super_class: #3    // java/lang/Object 
  7.   interfaces: 0, fields: 0, methods: 2, attributes: 1 
  8. Constant pool: 
  9.    #1 = Methodref          #3.#12         // java/lang/Object."<init>":()V 
  10.    #2 = Class              #13            // HelloWorld 
  11.    #3 = Class              #14            // java/lang/Object 
  12.    #4 = Utf8               <init> 
  13.    #5 = Utf8               ()V 
  14.    #6 = Utf8               Code 
  15.    #7 = Utf8               LineNumberTable 
  16.    #8 = Utf8               main 
  17.    #9 = Utf8               ([Ljava/lang/String;)V 
  18.   #10 = Utf8               SourceFile 
  19.   #11 = Utf8               HelloWorld.java 
  20.   #12 = NameAndType        #4:#5          // "<init>":()V 
  21.   #13 = Utf8               HelloWorld 
  22.   #14 = Utf8               java/lang/Object 
  23.   public HelloWorld(); 
  24.     descriptor: ()V 
  25.     flags: (0x0001) ACC_PUBLIC 
  26.     Code: 
  27.       stack=1, locals=1, args_size=1 
  28.          0: aload_0 
  29.          1: invokespecial #1                  // Method java/lang/Object."<init>":()V 
  30.          4: return 
  31.       LineNumberTable: 
  32.         line 1: 0 
  33.  
  34.   public static void main(java.lang.String[]); 
  35.     descriptor: ([Ljava/lang/String;)V 
  36.     flags: (0x0009) ACC_PUBLIC, ACC_STATIC 
  37.     Code: 
  38.       stack=2, locals=4, args_size=1 
  39.          0: iconst_1 
  40.          1: istore_1 
  41.          2: iconst_2 
  42.          3: istore_2 
  43.          4: iload_1 
  44.          5: iload_2 
  45.          6: iadd 
  46.          7: istore_3 
  47.          8: return 
  48.       LineNumberTable: 
  49.         line 3: 0 
  50.         line 4: 2 
  51.         line 5: 4 
  52.         line 6: 8 

好嘞。咱們都知道,上面這些就是Java的字節碼。有了上面這個輸出的內容,你把自己想像成虛擬機,來運行它,就理解了 Java 虛擬機里各個部分了。

首先,這部分內容,要執行,一定得先讀到內存里,負載讀這些內容的,就是虛擬機的類加載器。

加載進來的其實是個二進制流,然后呢,需要把它整理成對應格式的內容才方便使用嘛。比如這個類叫啥名字,繼承了誰,都有什么方法,方法名字叫啥,內容是什么這些東西要找個地方放著。放哪好呢?方法區就是干這個的。

所謂的運行時常量池也是方法區里的一塊區域。往上看Constant Pool 在運行時會被解析成 Run-time Constant Pool。如果涉及到對其他類的引用等等,會在加載之后再鏈接的時候,把這里面的符號引用轉化成直接引用。

另外一些部分呢?概括來講就是Java虛擬機棧,就是咱們常說的棧,是用來執行方法里的具體內容的。這一部分其實可以這樣理解。Java 虛擬機,和我們真實的物理機類似,都會把程序提供的指令執行,只不過虛擬機是一個提供了一套有限指令集的軟件。物理機基本都是基于寄存器執行,而 Java 虛擬機的對于指令的執行實現是基于棧的。

既然是棧,那棧里要放點什么?沒錯,是棧幀,英文是 Frames,就是咱們在使用 IDE debug 的時候看到的那一層一層的內容。

 

每個方法調用的時候,都會出現一幀,每一幀也是個結構,方法執行用到的東西都在里面。比如在 Debug 的時候,一般都會看到每個變量和值, 這些變量稱為本地變量(local variables),在上面的輸出內容里也有stack=2, locals=4, args_size=1 我們看到locals就是本地變量,args_size是方法參數的長度,還有一個就是操作數(stack),數值是棧的最大深度。

每個class 的任意一個方法里,都會有 frame ,它們都有自己的 local variables 本地變量表, 自己的operand stack 操作數棧,以及到run-time constant pool 運行時常量池的引用。當然,也可以有一些擴展信息,例如debug info。

那具體上面簡單的一個 1+2 這個操作,對應到 jvm 指令有這些:

  1. 0: iconst_1 
  2.          1: istore_1 
  3.          2: iconst_2 
  4.          3: istore_2 
  5.          4: iload_1 
  6.          5: iload_2 
  7.          6: iadd 
  8.          7: istore_3 
  9.          8: return 

具體當前執行到第幾條指令,需要有個標識,這個活兒讓程序計數器給干了。這小子一直指向下一條即將執行的指令。基本棧的實現,上面的指令大意是把常量1賦值給第一個變量,常量2賦值給第二個變量,之后,變量一入棧,變量二入棧,執行iadd操作的時候,這兩個數據出棧,完成求和,再賦值給變量3,入棧,再返回。下次咱們細說JVM指令的時候,再詳細說說。這些指令的執行,當然離不開執行引擎。

因為不需要執行Native方法,所以我們一般不用本地方法棧,這是給類似JNI這些本地方法實現準備的。

你看,觀察了1+2的過程,基本Java 虛擬機的結構是不是就理解了?:-) 如果還是記不住的話,你可以這樣想啊,Java 的世界里,經常會說到堆和棧。那棧用來存啥呢?想想你 debug 時候看到的那一層層的幀, 然后再想想今天的1+2的執行,應該就齊了。

本文轉載自微信公眾號「 Tomcat那些事兒」,可以通過以下二維碼關注。轉載本文請聯系 Tomcat那些事兒公眾號。

 

 

責任編輯:武曉燕 來源: Tomcat那些事兒
相關推薦

2022-05-03 00:03:11

狀態管理前端開發

2022-03-27 09:06:25

vuexActionsMutations

2024-03-15 08:23:26

異步編程函數

2019-09-29 06:12:38

交換機配置vlan

2019-12-26 09:15:44

網絡IOLinux

2012-11-30 11:19:02

JavaScript

2024-11-25 07:39:48

2022-10-20 18:43:32

C語言golang安全

2018-03-21 16:19:40

MVCMVPMVVM

2022-07-27 22:59:53

Node.jsNest

2019-09-16 08:32:59

遞歸算法編程

2012-11-14 09:57:46

JavaJava虛擬機JVM

2019-09-18 10:12:37

遞歸數據結構

2024-03-29 11:42:21

Java虛擬機

2019-07-24 16:04:47

Java虛擬機并發

2022-11-26 00:22:14

引用類型數組

2019-08-27 16:23:41

Docker虛擬化虛擬機

2009-08-18 22:06:59

VMware虛擬機軟件

2024-04-03 13:49:00

Java虛擬機方法區

2019-05-28 09:40:39

TCP協議socket接口
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91精品国模一区二区三区 | 97人人超碰| 中文字幕在线网 | 在线欧美视频 | 91在线影院 | 欧美5区| 国产综合久久 | 天天宗合网 | 国产剧情一区 | 九九综合九九 | 欧州一区| 黄色大片网| 一区二区三区视频在线免费观看 | 国产在线精品一区二区三区 | 国产精品久久亚洲 | 一区二区三区精品视频 | 日韩成人 | 午夜寂寞福利视频 | 久操伊人| 欧美一区二区在线 | 久久久高清 | 天天干b | 国产精品成人一区二区三区吃奶 | 国产精品一区二区免费 | 国产清纯白嫩初高生视频在线观看 | 久久久久久久久淑女av国产精品 | 亚洲精品久久久久久国产精华液 | 韩国欧洲一级毛片 | 久久99精品国产 | av在线播放国产 | 成人在线精品 | 成人免费视频网站在线看 | 亚洲电影中文字幕 | 国产精品成av人在线视午夜片 | av免费网址 | 超碰人人人 | 久久久久久久久毛片 | 中文字幕一区在线观看视频 | 日韩欧美高清 | 午夜网 | 在线观看a视频 |