成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

沒想到進入Main函數前,發生了這么多事!

開發 前端
最近這段時間,軒轅有些迷茫了,工作生活中一堆事兒,忙得我兩頭摸黑,很難找到時間靜下心來寫文章,就連你現在看到的這一篇還是我點燈熬油到1點鐘才寫完的。

[[388301]]

題外話

最近這段時間,軒轅有些迷茫了,工作生活中一堆事兒,忙得我兩頭摸黑,很難找到時間靜下心來寫文章,就連你現在看到的這一篇還是我點燈熬油到1點鐘才寫完的。

估計朋友們也有發現了,這段時間故事文章少了很多,確實是這樣,不像水文幾下完事兒,也不像普通技術文章按照標準流程走就行。故事文需要放空自己,有好的靈感才能一氣呵成。

這段時間有好幾個選題,都開了個頭,占了個坑,然后因為沒時間思考,所以一直留著···

 

所以今天,先寫了一篇別的頂一頂,故事文章大家再給我點時間吧,感謝各位老鐵的支持!

在之前的一篇文章中,聊過從創建進程到進入main函數,發生了什么?

但當時只是針對C/C++這樣的native語言,從操作系統(Linux & Windows)的層面去探討了程序的啟動過程,而對Java、Python這樣的基于虛擬機/解釋器的語言并未提及。

今天,咱們就一起來探索下在Java語言中,你寫的main方法又是怎么被執行到的?

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

先來回顧一下那篇文章,對于C/C++程序而言,從創建進程到進入main函數,主要就是經歷了四個階段:

  • 進程 & 主線程創建階段
  • 主線程啟動執行并進行進程級初始化操作(如加載系統動態鏈接庫)
  • 主線程進入可執行文件的入口(OEP)并進行C/C++運行時庫初始化
  • 從C/C++運行時庫調入main函數

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

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

只不過呢,對于C/C++程序而言,到這里就已經進入main函數了,話題就可以結束了,而對于Java程序,執行到JVM的main,一切才剛剛開始。

JVM的main

故事,要從JVM的main函數開始講起···

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

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

 

和咱們在上一篇分析的流程符合,進入這個程序啟動入口后,會經過一系列的調用,最后來到main函數:

 

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

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

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

 

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

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

可以看到main函數只是一個包裝,直接就進入了JLI_Launch中。

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

  • 參數解析,環境配置
  • 檢查Java運行環境
  • 加載JVM核心動態庫libjvm.so
  • 創建并初始化Java虛擬機對象

這些過程都不是我們這篇文章探究的目標,咱們繼續把目光聚焦在Java中的main函數是怎么得到調用的。

在JLI_Launch的結尾,調用了ContinueInNewThread,從這個函數的名字我們也能窺探它的作用。

 

這個函數還是一層封裝,內部調用了真正干活的函數ContinueInNewThread0:

 

接下來就是創建線程來繼續后面的事情了,不過創建線程涉及到操作系統API的調用,所以這個函數在不同版本的系統中都有對應的實現。來看傳給它的第一個參數,這是新線程啟動后將要執行的入口函數:JavaMain。

JavaMain

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

  1. int JNICALL  JavaMain(void * _args) { 
  2.   
  3.     // ... 
  4.     // 尋找啟動類 
  5.     mainClass = LoadMainClass(env, mode, what); 
  6.     // ... 
  7.     // 尋找啟動類中的main函數 
  8.     mainID = (*env)->GetStaticMethodID(env, mainClass, "main"
  9.                                        "([Ljava/lang/String;)V"); 
  10.     // ... 
  11.     // 調用它 
  12.     (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); 
  13.     // ... 

JavaMain中的細節挺多的,咱們抽出需要關心的,要調用咱們寫的main方法就像把大象關進冰箱一共三步:

  • 找到啟動類
  • 找到啟動類中的main方法
  • 調用它

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

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

進入Java世界

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

這個函數內部后面會來到:

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

最終,會創建Java方法棧幀,準備好模板解釋器,隨后轉向解釋器入口開始執行字節碼,正式進入Java世界!

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

總結

現在可以來回答這個問題了:從創建進程到Java的main方法,經歷了什么?

咱們來劃分三個大的階段:

第一階段:操作系統層面進程和主線程的創建

第二階段:主線程啟動執行并進入到Java可執行文件(exe/elf)中的main函數(C++層面)

第三階段:創建JVM,尋找啟動類中的main方法,啟動解釋器執行對應字節碼進入Java世界

本文轉載自微信公眾號「編程技術宇宙」,作者軒轅之風 。轉載本文請聯系 編程技術宇宙公眾號。

 

責任編輯:武曉燕 來源: 編程技術宇宙
相關推薦

2021-01-27 18:13:35

日志nginx信息

2022-11-29 09:12:12

硬件技術拼圖

2021-08-31 09:35:01

TCPIP漏洞

2020-08-14 08:19:25

Shell命令行數據

2021-11-29 05:37:24

Windows Def操作系統微軟

2019-12-09 10:13:20

HashMap選擇容量

2020-10-29 07:05:30

Main函數Python

2021-02-25 17:58:26

Python 開發編程語言

2016-10-11 14:19:07

2015-07-15 13:00:31

英特爾開源

2023-12-26 15:10:00

處理二進制文件

2020-06-08 08:38:24

可執行文件文件字符

2016-09-01 13:54:23

Google太空電梯懸滑板

2017-12-26 15:41:26

2019-12-16 09:10:46

碼農熊貓員工

2018-01-26 23:23:23

JDBC MySQL數據庫

2012-12-28 13:47:36

Raspberry PGeek

2017-02-09 17:00:00

iOSSwiftKVC

2022-01-05 17:13:28

監控HTTPS網站

2024-01-12 10:25:02

蓋茨ChatGPT
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本久久久久久 | 亚洲欧美日韩精品久久亚洲区 | 国产99久久精品一区二区永久免费 | 色偷偷人人澡人人爽人人模 | 国产一级片 | 精品少妇一区二区三区在线播放 | 国产精品一区二区三区久久 | 亚洲第一在线 | 免费观看国产视频在线 | 国产精品欧美一区二区三区不卡 | 毛片免费看 | 色网站在线 | 精品久久久精品 | 午夜网站视频 | av黄色免费在线观看 | 国产免费一区二区三区 | 国产目拍亚洲精品99久久精品 | 国产精品久久久久久久久久免费看 | 亚州精品天堂中文字幕 | 99在线国产 | 久久综合狠狠综合久久综合88 | 在线亚洲免费视频 | 久久精品日产第一区二区三区 | 在线观看中文字幕dvd播放 | 欧美日韩在线播放 | 成人在线一区二区 | 免费午夜视频 | 天天草草草 | 欧美aⅴ | 成人精品一区二区三区中文字幕 | 精品一区二区在线视频 | 亚洲精品一区中文字幕 | 青青伊人久久 | 综合久| 国产激情在线 | 午夜小视频在线播放 | 久久天堂网 | 在线电影日韩 | 国产一区久久 | 欧美影院久久 | 在线视频三区 |