java main方法背后的故事?(轉)


 

jvm java 看似一種語言,實則一個巨大的體系的王國,開發這么多年了,還是沒有搞懂,我以為我懂了,可是過了一段時間又忘了,所以說還是沒懂

1、main方法說起

編譯完我們的java文件后,需要有個一含有main方法的類,java 命令將指示操作系統啟動一個jvm進程

這個jvm進程啟動后,尋找那個main地方開始執行程序

java [JVM_Options] ClassName_with_main [args_separate_space]

main方法的簽名必須是 pubic static void main(String[] args) why?

簡單點:

首先,main方法是JVM(java虛擬機)自動調用

JVM調用main方法的位置自然不會在某個類中、或某個包中,因此只有當main方法在公有級別上時,才對JVM可見,所以mian方法需要public修飾,

main方法所在的類也需要public修飾符。

由於main方法是所有程序的入口,也就是main被調用時沒有任何對象創建,不通過對象調用某一方法,只有將該方法定義為靜態方法,所以main方法是一個靜態方法,既需要static修飾。

JVM對於java程序已經是最底層,由它調用的方法的返回值已經沒有任何地方可去,因此,main方法返回值為空,既需用void修飾。

至於main方法的參數String[ ] arg我們現在已經很少有機會去用它了,它用於在接受命令行傳入的參數

 2、執行main方法之前發生了神馬

可以參看 jvm源碼分析     

首先要明確 jvm進程 是操作系統的進程,該進程是多線程機制的

我們明確兩種線程:

jvm線程:指jvm自行管理的線程,我們在程序中無法操控,多是守護類型的

java線程:指從java技術角度看 jvm、我們在程序中用Thread類或Runnable接口編寫產生的線程,可操控的線程

至於 java線程 在 jvm里面是怎么實現的,怎么對應到os級別的線程的,請看  http://my.oschina.net/jingxing05/blog/275334

明確兩類不同的線程之后,執行main方法之前: LoadJavaVM

jvm進程啟動了多個jvm線程(很可能是錯的,如有,請賜教):

jvm線程:

  • 啟動 VM Thread, 單例的,所有線程之始祖!這個線程自輪詢loop從對一個隊列中取操作任務,來產生其他線程

  • 根據jvm抽象規范,可能有執行引擎線程GC線程classloader線程

在jvm自身啟動和初始化之后,會

ContinueInNewThread(JavaMain, threadStackSize, (void*)&args);

即啟動一個叫main的線程來執行  入口的main方法,main線程雖然不是我們手動生出的線程,但ta還是一個非守護線程

3、main執行過程

  • 加載類

執行main方法時,jvm進程發現main所在類沒有在方法區,於是開始進行classload

類加載完的最后一步是 根據情況決定  是不是要進行類的初始化

在main執行之前,必須先對類進行初始化。初始化類的變量,還有靜態代碼塊。初始化的時候還要先初始化它的父類。每個類都有一個隱含的父類Object。 

初始化的順序:類變量和靜態塊按序,先父后子

類的初始化過程發生時刻: 

1. T是一個類,當T的一個實例創建的時候,也就是T t = new T(); 

2. T的一個靜態方法被調用的時候,也就是 T.staticField(); 

3. T的靜態屬性被賦值的時候,T.staticField = o; 

4. T的一個靜態屬性被使用的時候,也就是 Object o = T.staticField; 但是它不是常量。 

5. T is a top level class , and an assert statement  lexically nested 

within T  is executed. (不懂,求解) 

  • 執行main方法

將方法需要的參數,局部變量,本地方法,操作數等以 棧幀的結構 push到 main線程的堆棧區,然后執行引擎線程開始執行,執行完畢,將該棧幀 pop掉。main線程的堆棧區沒有棧幀時,main線程消退。

  • 卸載類對象

這一步是個優化的步驟,釋放一些方法區的內存,jvm自己決定要不要這一步,一般不會去卸載方法區的

  • 程序退出

     

1. 所有的非daemon線程都終止了 

2. 某個線程調用了類Runtime或者System的exit方法

main程序執行圖

 

 

類加載詳細過程

 

jvm中的一些線程可參看 http://ifeve.com/jvm-thread/

http://my.oschina.net/jingxing05/blog/282867?p={{currentPage+1}}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM