1 Java Instrument能做什么?最大的作用?
使開發(fā)者可以構(gòu)建一個獨立于應(yīng)用程序的代理程序Agent,用來監(jiān)控和協(xié)助運行在JVM上的程序,更重要的是能夠替換和修改某些類的定義;
最大的作用:可以實現(xiàn)一種虛擬機級別支持的AOP實現(xiàn)方式;
2 在JDK 1.5 、1.6中,Java Instrument做了哪些變動支持?
JDK 1.5:支持靜態(tài)Instrument,就是在JVM啟動前靜態(tài)設(shè)置Instrument;
JDK 1.6:支持動態(tài)Instrument,就是在JVM啟動后動態(tài)設(shè)置Instrument;支持本地代碼Instrument;支持動態(tài)改變classpath;
3 Java Instrument的實現(xiàn)是基于JVM哪種機制?JVMTI是什么,可以做什么?
- 基于JVMTI代理程序;
- JVMTI:一套代理程序機制,為JVM相關(guān)工具提供的本地編程接口集合;
- JVMTI可以支持第三方工具程序以代理的方式連接和訪問JVM,并利用JVMTI提供的豐富的編程接口,完成很多跟JVM相關(guān)的功能;
4 Instrument premain、agentmain方法執(zhí)行時機?
- premain執(zhí)行時機:在JVM啟動時,初始化函數(shù)eventHandlerVMinit會調(diào)用sun.instrument.instrumentationImpl類的loadClassAndCallPremain方法去執(zhí)行Premain-Class指定類的premain方法;
- 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代表什么?分別會有什么作用?
- agentArgs:代理程序命令行中輸入?yún)?shù),隨同“-javaagent”一起傳入,與main函數(shù)不同的是,這個參數(shù)是一個字符串而不是一個字符串數(shù)組;
- inst:java.lang.instrument.Instrumentation實例,由JVM自動傳入,集中了幾乎所有功能方法,如:類操作、classpath操作等;
6 java.lang.instrument.ClassFileTransformer是什么,有什么作用?
- ClassFileTransformer當中的transform方法可以對類定義進行操作修改;
- 在類字節(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ù)清單?
- Premain-Class:指定包含premain方法的類名;
- Agent-Class:指定包含agentmain方法的類名;
- Boot-Class-Path:指定引導(dǎo)類加載器搜索的路徑列表。查找類的特點于平臺的機制失敗后,引導(dǎo)類加載器會搜索這些路徑;
- Can-Redefine-Class:是否能重新定義此代理所需的類,默認為false;
- Can-Retransform-Class:是否能重新轉(zhuǎn)換此代理所需的類,默認為false;
- Can-Set-Native-Method-Prefix:是否能設(shè)置此代理所需的本機方法前綴,默認值為false;
9 兩個核心API ClassFileTransformer、Instrumention?
- ClassFileTransformer:定義了類加載前的預(yù)處理類;
- 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工作原理?
- 在JVM啟動時,通過JVM參數(shù)-javaagent,傳入agent jar,Instrument Agent被加載;
- 在Instrument Agent 初始化時,注冊了JVMTI初始化函數(shù)eventHandlerVMinit;
- 在JVM啟動時,會調(diào)用初始化函數(shù)eventHandlerVMinit,啟動了Instrument Agent,用sun.instrument.instrumentationImpl類里的方法loadClassAndCallPremain方法去初始化Premain-Class指定類的premain方法;
- 初始化函數(shù)eventHandlerVMinit,注冊了class解析的ClassFileLoadHook函數(shù);
- 在解析Class之前,JVM調(diào)用JVMTI的ClassFileLoadHook函數(shù),鉤子函數(shù)調(diào)用sun.instrument.instrumentationImpl類里的transform方法,通過TransformerManager的transformer方法最終調(diào)用我們自定義的Transformer類的transform方法;
- 因為字節(jié)碼在解析Class之前改的,直接使用修改后的字節(jié)碼的數(shù)據(jù)流替代,最后進入Class解析,對整個Class解析無影響;
- 重新加載Class依然重新走5-6步驟;