真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

在Java語言中main方法是如何被執(zhí)行的

這篇文章主要講解了“在Java語言中main方法是如何被執(zhí)行的”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“在Java語言中main方法是如何被執(zhí)行的”吧!

棲霞網(wǎng)站制作公司哪家好,找成都創(chuàng)新互聯(lián)公司!從網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、APP開發(fā)、響應(yīng)式網(wǎng)站建設(shè)等網(wǎng)站項目制作,到程序開發(fā),運營維護(hù)。成都創(chuàng)新互聯(lián)公司于2013年開始到現(xiàn)在10年的時間,我們擁有了豐富的建站經(jīng)驗和運維經(jīng)驗,來保證我們的工作的順利進(jìn)行。專注于網(wǎng)站建設(shè)就選成都創(chuàng)新互聯(lián)公司

對于Java而言,其底層是Java虛擬機(jī)在跑著,也就是JVM,這篇文章如無特殊說明,默認(rèn)以Hotspot為研究對象。

先來回顧一下那篇文章,對于C/C++程序而言,從創(chuàng)建進(jìn)程到進(jìn)入main函數(shù),主要就是經(jīng)歷了四個階段:

  • 進(jìn)程 & 主線程創(chuàng)建階段

  • 主線程啟動執(zhí)行并進(jìn)行進(jìn)程級初始化操作(如加載系統(tǒng)動態(tài)鏈接庫)

  • 主線程進(jìn)入可執(zhí)行文件的入口(OEP)并進(jìn)行C/C++運行時庫初始化

  • 從C/C++運行時庫調(diào)入main函數(shù)

你知道的,Java的虛擬機(jī)JVM主要是C++編寫的,所以JVM本質(zhì)上也算是一個C++程序。

因此,上面的四個階段,對于JVM而言,同樣適用。

只不過呢,對于C/C++程序而言,到這里就已經(jīng)進(jìn)入main函數(shù)了,話題就可以結(jié)束了,而對于Java程序,執(zhí)行到JVM的main,一切才剛剛開始。

JVM的main

故事,要從JVM的main函數(shù)開始講起···

你應(yīng)該知道的,不管你是普通Java程序,還是用的Spring或者其他什么框架,最終的程序都是在一個Java進(jìn)程中運行的,這個進(jìn)程的可執(zhí)行文件就是一個exe(windows上)或者elf(linux上)。

咱們就從這個可執(zhí)行文件入手,以Linux系統(tǒng)上的Java8版本為例,用反匯編神器IDA打開可以看到,這個可執(zhí)行文件的入口:

在Java語言中main方法是如何被執(zhí)行的

和咱們在上一篇分析的流程符合,進(jìn)入這個程序啟動入口后,會經(jīng)過一系列的調(diào)用,最后來到main函數(shù):

在Java語言中main方法是如何被執(zhí)行的

反匯編看著好頭大,好在,HotSpot虛擬機(jī)有開源版本,咱們可以去OpenJDK中找來這個main函數(shù)的源碼瞧瞧。

不同版本差異還是挺大,這里以Java8為例:

代碼路徑:https://github.com/openjdk/jdk/blob/jdk8-b20/jdk/src/share/bin/main.c

在Java語言中main方法是如何被執(zhí)行的

在這個代碼中除了main函數(shù),還可以看到如果定義了JAVAW宏定義,則入口從main變成了WinMain函數(shù),做過Windows應(yīng)用程序開發(fā)的朋友這個時候應(yīng)該露出了滿意的微笑。

如果定義了JAVAW,則是一個Win32 GUI的程序,當(dāng)然在Linux上是肯定沒有這個宏定義的,不過這不是本文的主題。

可以看到main函數(shù)只是一個包裝,直接就進(jìn)入了JLI_Launch中。

這個函數(shù)位于同目錄下的隔壁java.c文件中,是JVM非常重要的初始化函數(shù),主要完成了下面幾件事情:

  • 參數(shù)解析,環(huán)境配置

  • 檢查Java運行環(huán)境

  • 加載JVM核心動態(tài)庫libjvm.so

  • 創(chuàng)建并初始化Java虛擬機(jī)對象

這些過程都不是我們這篇文章探究的目標(biāo),咱們繼續(xù)把目光聚焦在Java中的main函數(shù)是怎么得到調(diào)用的。

在JLI_Launch的結(jié)尾,調(diào)用了ContinueInNewThread,從這個函數(shù)的名字我們也能窺探它的作用。

在Java語言中main方法是如何被執(zhí)行的

這個函數(shù)還是一層封裝,內(nèi)部調(diào)用了真正干活的函數(shù)ContinueInNewThread0:

在Java語言中main方法是如何被執(zhí)行的

接下來就是創(chuàng)建線程來繼續(xù)后面的事情了,不過創(chuàng)建線程涉及到操作系統(tǒng)API的調(diào)用,所以這個函數(shù)在不同版本的系統(tǒng)中都有對應(yīng)的實現(xiàn)。來看傳給它的第一個參數(shù),這是新線程啟動后將要執(zhí)行的入口函數(shù):JavaMain。

JavaMain

這個函數(shù)的名字就有點意思了,看起來,快要進(jìn)入Java的地界兒了,加油繼續(xù)看下去:

int JNICALL  JavaMain(void * _args) {       // ...     // 尋找啟動類     mainClass = LoadMainClass(env, mode, what);     // ...     // 尋找啟動類中的main函數(shù)     mainID = (*env)->GetStaticMethodID(env, mainClass, "main",                                        "([Ljava/lang/String;)V");     // ...     // 調(diào)用它     (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);     // ... }

JavaMain中的細(xì)節(jié)挺多的,咱們抽出需要關(guān)心的,要調(diào)用咱們寫的main方法就像把大象關(guān)進(jìn)冰箱一共三步:

  • 找到啟動類

  • 找到啟動類中的main方法

  • 調(diào)用它

具體尋找的過程這里就不展開了,有些繁瑣,但你應(yīng)該能猜到,Java代碼編譯后都是以class文件的形式存儲的,所以這個尋找的背后少不了要涉及到class類加載等一系列的工作。

總之,一頓操作猛如虎,嘿,JVM把咱們寫的main方法找到了!接下來就是調(diào)用它了。

進(jìn)入Java世界

調(diào)用main方法的是CallStaticVoidMethod,從名字可以看到,這是在調(diào)用一個靜態(tài)的、返回值為空的方法。注意了,C++的地盤快到邊境了,咱們即將通過它來到美麗的Java新世界!

這個函數(shù)內(nèi)部后面會來到:

JavaCalls::call(result, method, &java_args, CHECK);

最終,會創(chuàng)建Java方法棧幀,準(zhǔn)備好模板解釋器,隨后轉(zhuǎn)向解釋器入口開始執(zhí)行字節(jié)碼,正式進(jìn)入Java世界!

進(jìn)入Java世界第一站,就是前面找到的啟動類的main方法,在這里開啟程序在Java世界的征程。

感謝各位的閱讀,以上就是“在Java語言中main方法是如何被執(zhí)行的”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對在Java語言中main方法是如何被執(zhí)行的這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!


當(dāng)前文章:在Java語言中main方法是如何被執(zhí)行的
標(biāo)題來源:http://weahome.cn/article/ggjcds.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部