JVM中的Hello World是如何執行的?

oschina發表於2015-03-21

每一個Java開發者都是通過Hello World敲開物件導向世界的大門。但是在一開始,我們考慮的只是這個語言是什麼樣的,我們如何更好的編碼,卻很少有人關心他內部是怎麼執行的。看下面一個簡單的hello world。

package com.wordpress.kkarthikeyanblog;  

public class HelloWorld {  

public static String HELLOWORLD = "Hello World";  

public void print() {  
System.out.println(HELLOWORLD);  
}  

public static void main(String[] args) {  
HelloWorld helloWorld = new HelloWorld();  
helloWorld.print();  
}  
}

在使用javac工具編譯了以上程式碼後,我使用下面的命令來執行這個程式。這時候JVM就啟動了。

java com/wordpress/kkarthikeyanblog/HelloWorld

JVM的自述

Hey,Guys,我是JVM,讓我來給大家說說我是如何執行這個程式的。

在一開始,BoostrapperClassLoader 載入java.lang.package這個包,我內部的System Class Loader通過給定的classpath找到類”HelloWorld”。在定位到HelloWorld.class後,我將得到這個二進位制流。然後我從這個class檔案中提取出了一下資訊。

  • constants(例如文字、常數、型別、方法的符號引用)將被放到constant pool【在這個例子中包括HelloWorld class、方法、常量的符號】
  • 包、修飾符、靜態變數【在這個例子中,”HELLOWORLD”這個靜態變數】
  • 欄位資訊(名稱、型別、修飾符)
  • 方法資訊(名稱、返回值型別、方法引數、修飾符、方法的位元組碼)【在這個例子中是print、void、public和位元組碼】
  • ClassLoader的引用【裝載這個類的classloader】
  • 引用class的類

以上資訊都被存在”Method Area”中。

在裝載完畢以上資訊後,我(JVM)試著找出”public static void main(String [] args)”方法。

我(JVM)中的每一個執行緒,除了共享”Method area”和”Heap Space”之外,他們還擁有自己的”stack”和”pc register”。

我(JVM)將從Method area中獲取的main()方法資訊壓入棧(push),程式計數暫存器(pc register)將會告訴我下一步該幹什麼。

然後在程式計數器的指引下,我開始執行下面這行:

HelloWorld helloWorld = new HelloWorld();

我(JVM)將從constant pool中拿到HelloWorld的符號引用。然後查詢Method area,獲取到class資訊,然後在Heap space中建立物件。

現在程式計數器將會指到

helloWorld.print();

我(JVM)將從我自己的執行緒的stack中取出變數”helloworld”的引用,並且找到print()方法。在從Method Area中得到位元組碼資訊後,我將方法”print()”壓棧(push),現在我將開始執行print()方法。

一旦print()方法執行結束,這個方法將出棧(pop up),將繼續執行main()方法。一旦main()方法結束。main()方法將出棧,整個程式的執行也就結束了。

總結一下以上所說,在JVM中:

Method area-存放類資訊

Heap Space-只存放物件

針對每一個執行緒來講:

Stack-包含一個一個的棧幀【例如方法棧】-它也存放指定方法的區域性變數

程式計數暫存器-指導下一步該執行什麼。

另外,除了這些,還有一個”Garbage Collector”(垃圾回收器)來釋放那些無用的物件。

最後,希望你看了此文能對JVM有更深一步的瞭解。

相關文章