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

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

  1. 使開發者能夠構建一個獨立於應用程序的代理程序Agent,用來監控和協助運行在JVM上的程序,更重要的是可以替換和修改某些類的定義;java

  2. 最大的做用:能夠實現一種虛擬機級別支持的AOP實現方式;編程

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

  1. JDK 1.5:支持靜態Instrument,就是在JVM啓動前靜態設置Instrument;數組

  2. JDK 1.6:支持動態Instrument,就是在JVM啓動後動態設置Instrument;支持本地代碼Instrument;支持動態改變classpath;app

3 Java Instrument的實現是基於JVM哪一種機制?JVMTI是什麼,能夠作什麼?

  1. 基於JVMTI代理程序;
  2. JVMTI:一套代理程序機制,爲JVM相關工具提供的本地編程接口集合;
  3. JVMTI能夠支持第三方工具程序以代理的方式鏈接和訪問JVM,並利用JVMTI提供的豐富的編程接口,完成不少跟JVM相關的功能;

4 Instrument premain、agentmain方法執行時機?

  1. premain執行時機:在JVM啓動時,初始化函數eventHandlerVMinit會調用sun.instrument.instrumentationImpl類的loadClassAndCallPremain方法去執行Premain-Class指定類的premain方法;
  2. agentmain執行時機:在JVM啓動後,經過VirtualMachine附着一個Instrument,如:vm.loadAgent(jar),會調用sun.instrument.instrumentationImpl類的loadClassAndCallAgentmain方法去執行Agentmain-Class指定類的agentmain方法;

5 Instrument premain、agentmain方法中兩個參數agentArgs、inst表明什麼?分別會有什麼做用?

  1. agentArgs:代理程序命令行中輸入參數,隨同「-javaagent」一塊兒傳入,與main函數不一樣的是,這個參數是一個字符串而不是一個字符串數組;
  2. inst:java.lang.instrument.Instrumentation實例,由JVM自動傳入,集中了幾乎全部功能方法,如:類操做、classpath操做等;

6 java.lang.instrument.ClassFileTransformer是什麼,有什麼做用?

  1. ClassFileTransformer當中的transform方法能夠對類定義進行操做修改;
  2. 在類字節碼載入JVM前,JVM會調用ClassFileTransformer.transform方法,從而實現對類定義進行操做修改,實現AOP功能;相對於JDK 動態代理、CGLIB等AOP實現技術,不會生成新類,也不須要原類有接口;

7 對於agentmain方法執行,如何進行動態attach agent?

經過VirtualMachine附着一個Instrument,如:vm.loadAgent(jar);函數

8 META-INF/MAINFEST.MF參數清單?

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

9 兩個核心API ClassFileTransformer、Instrumention?

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

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

(2)retransformerClasses:指定哪些類,在已加載的狀況下,從新進行轉換處理,即觸發從新加載類定義;對於從新加載的類不能修改舊有的類聲明,好比:不能增長屬性、不能修改方法聲明等;spa

(3)redefineClasses:指定哪些類,觸發從新加載類定義,與上面不一樣的是不會從新進行轉換處理,而是把處理結果bytecode直接給JVM;命令行

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

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

(6)getObjectSize:得到一個對象佔用的空間大小;

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

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

10 Java Instrument工做原理?

  1. 在JVM啓動時,經過JVM參數-javaagent,傳入agent jar,Instrument Agent被加載;
  2. 在Instrument Agent 初始化時,註冊了JVMTI初始化函數eventHandlerVMinit;
  3. 在JVM啓動時,會調用初始化函數eventHandlerVMinit,啓動了Instrument Agent,用sun.instrument.instrumentationImpl類裏的方法loadClassAndCallPremain方法去初始化Premain-Class指定類的premain方法;
  4. 初始化函數eventHandlerVMinit,註冊了class解析的ClassFileLoadHook函數;
  5. 在解析Class以前,JVM調用JVMTI的ClassFileLoadHook函數,鉤子函數調用sun.instrument.instrumentationImpl類裏的transform方法,經過TransformerManager的transformer方法最終調用咱們自定義的Transformer類的transform方法;
  6. 由於字節碼在解析Class以前改的,直接使用修改後的字節碼的數據流替代,最後進入Class解析,對整個Class解析無影響;
  7. 從新加載Class依然從新走5-6步驟;
相關文章
相關標籤/搜索