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中的一些執行緒可參看點選開啟連結
原文轉自:點選開啟連結
相關文章
- 更好的 java 重試框架 sisyphus 背後的故事Java框架
- 《碼出高效:Java開發手冊》背後的故事Java
- Redis持久化背後的故事Redis持久化
- 專利背後的故事 | 一種郵件安全控制方法
- Java - 25 main方法JavaAI
- dyld背後的故事&原始碼分析原始碼
- GCC編譯器背後的故事GC編譯
- 愛回收IPO背後的新老故事
- RestCloud ETL 社群版背後的故事RESTCloud
- 郭超:阿里雲Cassandra背後的故事阿里
- 和 .project 檔案說“再見”—— VS Code Java 1.1.0 背後的故事ProjectJava
- 蘋果自動駕駛背後的故事蘋果自動駕駛
- 嵌入式—編譯器背後的故事編譯
- 安能物流 All in TiDB 背後的故事與成果TiDB
- 請求 www.baidu.com 背後的故事AI
- 你不知道的《阿里巴巴Java開發手冊》背後故事阿里Java
- 誰來背鍋?自動駕駛車禍背後的故事自動駕駛
- 【前端軼事】Chrome 小恐龍背後的故事前端Chrome
- 編譯器背後的故事(入門練習)編譯
- 聊聊百度搜尋背後的故事
- 開源筆記軟體 Joplin 背後的故事筆記
- 4399《胡偵探傳說》系列背後的故事
- 騰訊與Github的魔幻會面背後的故事…Github
- CVE-2016-1779技術分析及其背後的故事
- 《百英雄傳》眾籌450萬美元背後的故事
- What CANN Can?一輛小車背後的智慧故事
- 我們的20年 | 講述雲安全背後的故事
- 滑鼠打字的背後,隱藏著一個感人的故事
- Java中main方法引數String[ ] args的使用JavaAI
- 揭祕電子遊戲背後音效製作的故事遊戲
- 為你揭祕小程式音視訊背後的故事......
- 微信支付商戶系統架構背後的故事架構
- 一段《生化危機》音效背後的離奇故事
- Main()方法AI
- 2022 GDC EGW分享:《時之形》創作背後故事
- 功能遊戲爆款的誕生之路,《家國夢》背後的故事遊戲
- 解析UCloud人工智慧與英特爾背後的技術故事「上」Cloud人工智慧
- 解析UCloud人工智慧與英特爾背後的技術故事「下」Cloud人工智慧
- 最新訪談首次披露拍出「天價」AI畫作背後的故事AI