自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

居然還有方式可以查看Java方法的匯編代碼,真是神奇

開(kāi)發(fā) 后端
當(dāng)我們?cè)谘芯縥ava的內(nèi)部實(shí)現(xiàn)時(shí),經(jīng)常會(huì)需要查看java方法的字節(jié)碼,有時(shí)為了確定一些問(wèn)題,甚至還需要查看某些方法在jit編譯后的匯編代碼。

 [[350157]]

當(dāng)我們?cè)谘芯縥ava的內(nèi)部實(shí)現(xiàn)時(shí),經(jīng)常會(huì)需要查看java方法的字節(jié)碼,有時(shí)為了確定一些問(wèn)題,甚至還需要查看某些方法在jit編譯后的匯編代碼。

這篇文章我們從零開(kāi)始,詳細(xì)說(shuō)一下如何查看java方法的字節(jié)碼以及匯編代碼,希望能給有這方面困惑的同學(xué)提供一些幫助。

為了真正意義上的從零開(kāi)始,我們自己動(dòng)手,通過(guò)源碼構(gòu)建一個(gè)屬于我們自己的jdk,該過(guò)程雖然不是必須的,但了解這些過(guò)程,對(duì)于我們理解后文,以及后續(xù)的jvm研究,都是有一定的幫助的。

首先,下載jdk源碼:

  1. $ git clone https://github.com/openjdk/jdk.git 

源碼下載完畢后,我們看下jdk內(nèi)部大致的目錄結(jié)構(gòu):

 

該目錄中的 doc/building.html 詳細(xì)說(shuō)明了如何構(gòu)建一個(gè)jdk,有興趣的同學(xué)可以好好看下。

在jdk目錄里,我們執(zhí)行以下命令,要求構(gòu)建一個(gè)debug版本的jdk,并指定其安裝路徑為jdk-build:

  1. $ bash configure --with-debug-level=slowdebug --with-native-debug-symbols=internal --prefix=$HOME/jdk-build 

如果該命令執(zhí)行過(guò)程中沒(méi)有問(wèn)題,則會(huì)有類(lèi)似于下圖的輸出:

 

configure命令執(zhí)行成功后,我們?cè)賵?zhí)行下面的命令,開(kāi)始真正構(gòu)建jdk,并將構(gòu)建成功后的jdk安裝到j(luò)dk-build目錄里:

  1. $ make images 
  2. $ make install 

以上兩個(gè)命令成功后,我們可以切換到j(luò)dk-build目錄,看下新構(gòu)建的jdk:

 

好了,我們已經(jīng)有了自己的jdk了,下面我們可以用它來(lái)查看java方法的字節(jié)碼及匯編代碼。

首先,準(zhǔn)備下列文件:

 

我們先來(lái)看下如何查看字節(jié)碼,這個(gè)大家應(yīng)該都知道,但我這里還是演示下:

 

上圖是通過(guò)jdk自帶的javap命令來(lái)查看java的字節(jié)碼,其實(shí)還有很多其他的方式,比如各種ide中集成的工具,這里我們就不一一演示了。

javap還有很多參數(shù),比如 -p -v 等都非常有用,有興趣的可以自己試下。

字節(jié)碼就說(shuō)這些,下面我們主要來(lái)看下如何查看java方法的匯編代碼。

想要查看java方法在jit編譯后的匯編代碼,我們不僅要在執(zhí)行java命令時(shí)指定一些參數(shù),還需要一個(gè)額外的小工具,來(lái)輔助我們解匯編代碼。

如果沒(méi)有這個(gè)工具,jvm輸出的是機(jī)器碼,是不可讀的,有了這個(gè)工具,它可以幫我們自動(dòng)將機(jī)器碼轉(zhuǎn)成匯編代碼,非常方便。

這個(gè)工具就是hsdis,它的源碼就在jdk里,但構(gòu)建jdk的過(guò)程并不會(huì)構(gòu)建這個(gè)工具,如果我們想要使用它,要單獨(dú)構(gòu)建。

 

由上圖可見(jiàn),該工具還是非常簡(jiǎn)單的,它主要是通過(guò)調(diào)用gnu的binutils來(lái)解jvm輸出的匯編代碼,該工具的詳細(xì)構(gòu)建過(guò)程可以參考README和Makefile。

因?yàn)樵摴ぞ咭蕾?lài)gnu binutils解碼,所以我們要先下載binutils:

 

下載完binutils后,我們執(zhí)行以下命令,開(kāi)始構(gòu)建hsdis:

  1. $ make BINUTILS=binutils-2.35.1 all64 

如果沒(méi)有問(wèn)題的話,最終會(huì)在build/linux-amd64目錄下生成一個(gè)hsdis-amd64.so文件:

 

將該文件拷貝到我們之前構(gòu)建好的jdk里:

 

好,準(zhǔn)備工作已經(jīng)完成,現(xiàn)在我們可以通過(guò)指定一些參數(shù),來(lái)查看java方法的匯編代碼了。

我們還是用上面那個(gè)java類(lèi)T.java,假設(shè)我們想查看方法f1在jit編譯后的匯編代碼,可以使用下面的命令:

 

該命令會(huì)輸出很多內(nèi)容,而下圖中的就是我們想要的:

 

看到?jīng)],真的是匯編,且選中行就是方法f1的相加邏輯。

我們可以通過(guò)不同的參數(shù)來(lái)指定要查看的某個(gè)方法或某些方法,我們也可以通過(guò)-XX:+PrintAssembly參數(shù),來(lái)查看所有被jit編譯的方法。

有關(guān)各參數(shù)的使用及意義,請(qǐng)參考以下鏈接:

https://docs.oracle.com/en/java/javase/15/docs/specs/man/java.html

查看java方法的匯編代碼,對(duì)于我們理解java的內(nèi)部實(shí)現(xiàn),是非常有意義的,通過(guò)這種方式的輔助,我們可以理解很多文檔上難以理解的內(nèi)容,比如 volatile。

本文轉(zhuǎn)載自微信公眾號(hào)「卯時(shí)卯刻」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系卯時(shí)卯刻公眾號(hào)。

 

責(zé)任編輯:武曉燕 來(lái)源: 卯時(shí)卯刻
相關(guān)推薦

2021-08-10 10:48:39

拷貝代碼架構(gòu)耦合

2021-02-04 08:01:35

RedisRDBAOF

2020-08-20 08:39:54

CTO代碼數(shù)據(jù)

2024-04-24 11:27:16

字典推導(dǎo)式Python

2021-01-01 14:36:03

Python開(kāi)發(fā)語(yǔ)言

2012-03-19 15:44:39

代碼

2017-04-05 11:10:23

Javascript代碼前端

2021-08-10 10:25:16

HTML 網(wǎng)絡(luò)開(kāi)發(fā)前端開(kāi)

2015-04-14 09:46:09

Apple Watch秘密

2021-12-29 07:44:51

Proto代碼微服務(wù)

2021-11-16 12:25:14

jsPPT前端

2024-01-03 08:12:10

計(jì)算求和Python內(nèi)置函數(shù)

2021-11-02 16:25:41

Python代碼技巧

2022-04-08 08:01:07

IPv4地址IPv6

2020-04-14 11:34:15

Linux命令行查看圖像

2021-04-15 15:20:46

PythonProperty裝飾器

2020-11-01 17:11:51

time.sleep暫停代碼Python

2025-04-08 08:12:26

Next.js組件ChatGPT

2022-11-16 08:33:29

監(jiān)聽(tīng)Spring監(jiān)聽(tīng)器

2016-10-11 17:21:30

IT
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)