python字节码解析_从底层入手,解析字节码增强和Btrace应用
這篇文章聊下字節(jié)碼和相關(guān)的應(yīng)用。
1、機(jī)器碼和字節(jié)碼
機(jī)器碼(machine code),學(xué)名機(jī)器語言指令,有時(shí)也被稱為原生碼(Native Code),是電腦的CPU可直接解讀的數(shù)據(jù)。
通常意義上來理解的話,機(jī)器碼就是計(jì)算機(jī)可以直接執(zhí)行,并且執(zhí)行速度最快的代碼。
用機(jī)器語言編寫程序,編程人員要首先熟記所用計(jì)算機(jī)的全部指令代碼和代碼的涵義。手編程序時(shí),程序員得自己處理每條指令和每一數(shù)據(jù)的存儲(chǔ)分配和輸入輸出,還得記住編程過程中每步所使用的工作單元處在何種狀態(tài)。這是一件十分繁瑣的工作,編寫程序花費(fèi)的時(shí)間往往是實(shí)際運(yùn)行時(shí)間的幾十倍或幾百倍。而且,編出的程序全是些0和1的指令代碼,直觀性差,還容易出錯(cuò)。
字節(jié)碼(Bytecode)是一種包含執(zhí)行程序、由一序列 op 代碼/數(shù)據(jù)對 組成的二進(jìn)制文件。字節(jié)碼是一種中間碼,它比機(jī)器碼更抽象,需要直譯器轉(zhuǎn)譯后才能成為機(jī)器碼的中間代碼。
通常情況下它是已經(jīng)經(jīng)過編譯,但與特定機(jī)器碼無關(guān)。字節(jié)碼通常不像源碼一樣可以讓人閱讀,而是編碼后的數(shù)值常量、引用、指令等構(gòu)成的序列。
字節(jié)碼主要為了實(shí)現(xiàn)特定軟件運(yùn)行和軟件環(huán)境、與硬件環(huán)境無關(guān)。字節(jié)碼的實(shí)現(xiàn)方式是通過編譯器和虛擬機(jī)器。編譯器將源碼編譯成字節(jié)碼,特定平臺(tái)上的虛擬機(jī)器將字節(jié)碼轉(zhuǎn)譯為可以直接執(zhí)行的指令。
字節(jié)碼的典型應(yīng)用為Java bytecode。字節(jié)碼在運(yùn)行時(shí)通過JVM(JAVA虛擬機(jī))做一次轉(zhuǎn)換生成機(jī)器指令,因此能夠更好的跨平臺(tái)運(yùn)行。
2、字節(jié)碼增強(qiáng)技術(shù)
Java字節(jié)碼增強(qiáng)指的是在Java字節(jié)碼生成之后,對其進(jìn)行修改,增強(qiáng)其功能,這種方式相當(dāng)于對應(yīng)用程序的二進(jìn)制文件進(jìn)行修改。Java字節(jié)碼增強(qiáng)主要是為了減少冗余代碼,提高性能等。
實(shí)現(xiàn)字節(jié)碼增強(qiáng)的主要步驟為:
(1)修改字節(jié)碼
在內(nèi)存中獲取到原來的字節(jié)碼,然后通過一些工具(如 ASM,Javaasist)來修改它的byte[]數(shù)組,得到一個(gè)新的byte數(shù)組。
(2)使修改后的字節(jié)碼生效
有兩種方法:
- 自定義ClassLoader來加載修改后的字節(jié)碼;
- 替換掉原來的字節(jié)碼:在JVM加載用戶的Class時(shí),攔截,返回修改后的字節(jié)碼;或者在運(yùn)行時(shí),使用Instrumentation.redefineClasses方法來替換掉原來的字節(jié)碼;
3、字節(jié)碼增強(qiáng)有哪些實(shí)現(xiàn)
字節(jié)碼增強(qiáng)技術(shù)有以下這些:
- 動(dòng)態(tài)代理
- CGLIB
- Javassist
- asm
以 ASM 為例, 使用它可以動(dòng)態(tài)修改類、方法,甚至可以重新定義類,連 CGLib 底層都是用 ASM 實(shí)現(xiàn)的。
4、Btrace原理和應(yīng)用
BTrace是SUN Kenai云計(jì)算開發(fā)平臺(tái)下的一個(gè)開源項(xiàng)目,旨在為java提供安全可靠的動(dòng)態(tài)跟蹤分析工具。
那么,BTrace這么神奇的功能是如何實(shí)現(xiàn)的呢?既然這是個(gè)開源的代碼,那么直接從代碼找原理。BTrace代碼開源在https://github.com/btraceio/btrace。
BTrace是基于動(dòng)態(tài)字節(jié)碼修改技術(shù)(Hotswap)來實(shí)現(xiàn)運(yùn)行時(shí)java程序的跟蹤和替換。大體的原理可以用下面的公式描述:
Client(Java compile api + attach api) + Agent(腳本解析引擎 + ASM + JDK6 Instumentation) + SocketBTrace工作時(shí)序圖如下:
BTrace就是使用ASM修改當(dāng)前類,附加調(diào)試信息,得到新的類,一般情況下,Class文件是通過javac編譯器產(chǎn)生的,然后通過類加載器加載到虛擬機(jī)內(nèi),再通過執(zhí)行引擎去執(zhí)行。現(xiàn)在可以通過ASM的API直接生成符合Java虛擬機(jī)規(guī)范的Class字節(jié)流,這樣,ASM做的事情一定程度上正是javac解釋器做的工作。
5、總結(jié)
字節(jié)碼增強(qiáng)技術(shù)可以動(dòng)態(tài)地對運(yùn)行中的程序做修改,也可以跟蹤JVM運(yùn)行中程序的狀態(tài)。此外,我們平時(shí)使用的動(dòng)態(tài)代理、AOP也與字節(jié)碼增強(qiáng)密切相關(guān),它們實(shí)質(zhì)上還是利用各種手段生成符合規(guī)范的字節(jié)碼文件。
掌握字節(jié)碼增強(qiáng)后可以高效地定位并快速修復(fù)一些棘手的問題(如線上性能問題、方法出現(xiàn)不可控的出入?yún)⑿枰o急加日志等問題),也可以在開發(fā)中減少冗余代碼,大大提高開發(fā)效率。
關(guān)注公眾號:架構(gòu)進(jìn)化論,獲得第一手的技術(shù)資訊和原創(chuàng)文章總結(jié)
以上是生活随笔為你收集整理的python字节码解析_从底层入手,解析字节码增强和Btrace应用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 保存本地乱码_请教大神,如
- 下一篇: a标签点击后变色_中国科学家研发的不退色