☆技術(shù)問答集錦(13)Java Instrument原理

1 Java Instrument能做什么?最大的作用?

  1. 使開發(fā)者可以構(gòu)建一個獨立于應(yīng)用程序的代理程序Agent,用來監(jiān)控和協(xié)助運行在JVM上的程序,更重要的是能夠替換和修改某些類的定義;

  2. 最大的作用:可以實現(xiàn)一種虛擬機級別支持的AOP實現(xiàn)方式;

2 在JDK 1.5 、1.6中,Java Instrument做了哪些變動支持?

  1. JDK 1.5:支持靜態(tài)Instrument,就是在JVM啟動前靜態(tài)設(shè)置Instrument;

  2. JDK 1.6:支持動態(tài)Instrument,就是在JVM啟動后動態(tài)設(shè)置Instrument;支持本地代碼Instrument;支持動態(tài)改變classpath;

3 Java Instrument的實現(xiàn)是基于JVM哪種機制?JVMTI是什么,可以做什么?

  1. 基于JVMTI代理程序;
  2. JVMTI:一套代理程序機制,為JVM相關(guān)工具提供的本地編程接口集合;
  3. JVMTI可以支持第三方工具程序以代理的方式連接和訪問JVM,并利用JVMTI提供的豐富的編程接口,完成很多跟JVM相關(guān)的功能;

4 Instrument premain、agentmain方法執(zhí)行時機?

  1. premain執(zhí)行時機:在JVM啟動時,初始化函數(shù)eventHandlerVMinit會調(diào)用sun.instrument.instrumentationImpl類的loadClassAndCallPremain方法去執(zhí)行Premain-Class指定類的premain方法;
  2. agentmain執(zhí)行時機:在JVM啟動后,通過VirtualMachine附著一個Instrument,如:vm.loadAgent(jar),會調(diào)用sun.instrument.instrumentationImpl類的loadClassAndCallAgentmain方法去執(zhí)行Agentmain-Class指定類的agentmain方法;

5 Instrument premain、agentmain方法中兩個參數(shù)agentArgs、inst代表什么?分別會有什么作用?

  1. agentArgs:代理程序命令行中輸入?yún)?shù),隨同“-javaagent”一起傳入,與main函數(shù)不同的是,這個參數(shù)是一個字符串而不是一個字符串數(shù)組;
  2. inst:java.lang.instrument.Instrumentation實例,由JVM自動傳入,集中了幾乎所有功能方法,如:類操作、classpath操作等;

6 java.lang.instrument.ClassFileTransformer是什么,有什么作用?

  1. ClassFileTransformer當中的transform方法可以對類定義進行操作修改;
  2. 在類字節(jié)碼載入JVM前,JVM會調(diào)用ClassFileTransformer.transform方法,從而實現(xiàn)對類定義進行操作修改,實現(xiàn)AOP功能;相對于JDK 動態(tài)代理、CGLIB等AOP實現(xiàn)技術(shù),不會生成新類,也不需要原類有接口;

7 對于agentmain方法執(zhí)行,如何進行動態(tài)attach agent?

通過VirtualMachine附著一個Instrument,如:vm.loadAgent(jar);

8 META-INF/MAINFEST.MF參數(shù)清單?

  1. Premain-Class:指定包含premain方法的類名;
  2. Agent-Class:指定包含agentmain方法的類名;
  3. Boot-Class-Path:指定引導(dǎo)類加載器搜索的路徑列表。查找類的特點于平臺的機制失敗后,引導(dǎo)類加載器會搜索這些路徑;
  4. Can-Redefine-Class:是否能重新定義此代理所需的類,默認為false;
  5. Can-Retransform-Class:是否能重新轉(zhuǎn)換此代理所需的類,默認為false;
  6. Can-Set-Native-Method-Prefix:是否能設(shè)置此代理所需的本機方法前綴,默認值為false;

9 兩個核心API ClassFileTransformer、Instrumention?

  1. ClassFileTransformer:定義了類加載前的預(yù)處理類;
  2. Instrumentation:增強器

(1)add/removeTransformer:添加/刪除ClasFileTransformer;

(2)retransformerClasses:指定哪些類,在已加載的情況下,重新進行轉(zhuǎn)換處理,即觸發(fā)重新加載類定義;對于重新加載的類不能修改舊有的類聲明,比如:不能增加屬性、不能修改方法聲明等;

(3)redefineClasses:指定哪些類,觸發(fā)重新加載類定義,與上面不同的是不會重新進行轉(zhuǎn)換處理,而是把處理結(jié)果bytecode直接給JVM;

(4)getAllLoadedClasses:獲取當前已加載的Class集合;

(5)getInitiatedClasses:獲取由某個特定ClassLoader加載的類定義;

(6)getObjectSize:獲得一個對象占用的空間大?。?/p>

(7)appendToBootstrapClassLoaderSearch/appentToSystemClassLoaderSearch:增加BootstrapClassLoader/SystemClassLoader搜索路徑;

(8)isNativeMethodPrefixSupported/SetNativeMethodPrefix:判斷JVM是否支持攔截Native Method;

10 Java Instrument工作原理?

  1. 在JVM啟動時,通過JVM參數(shù)-javaagent,傳入agent jar,Instrument Agent被加載;
  2. 在Instrument Agent 初始化時,注冊了JVMTI初始化函數(shù)eventHandlerVMinit;
  3. 在JVM啟動時,會調(diào)用初始化函數(shù)eventHandlerVMinit,啟動了Instrument Agent,用sun.instrument.instrumentationImpl類里的方法loadClassAndCallPremain方法去初始化Premain-Class指定類的premain方法;
  4. 初始化函數(shù)eventHandlerVMinit,注冊了class解析的ClassFileLoadHook函數(shù);
  5. 在解析Class之前,JVM調(diào)用JVMTI的ClassFileLoadHook函數(shù),鉤子函數(shù)調(diào)用sun.instrument.instrumentationImpl類里的transform方法,通過TransformerManager的transformer方法最終調(diào)用我們自定義的Transformer類的transform方法;
  6. 因為字節(jié)碼在解析Class之前改的,直接使用修改后的字節(jié)碼的數(shù)據(jù)流替代,最后進入Class解析,對整個Class解析無影響;
  7. 重新加載Class依然重新走5-6步驟;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容