JVM中的Hello World
每一個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的類
在裝載完畢以上信息后,我(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有更深一步的了解。
本文由用戶 openkk 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!