Java Agent入門實戰(二)-Instrumentation源碼概述

Instrumentation接口設計初衷是爲了收集Java程序運行時的數據,用於監控運行程序狀態,記錄日誌,分析代碼用的。接下來從源碼的流程來介紹一下java

實現類InstrumentationImpl的void addTransformer(ClassFileTransformer transformer, boolean canRetransform);編程

從這段代碼知道,轉換器ClassFileTransformer的實現是存儲在TransformerManager的TransformerInfo數組中的,數組初始長度爲0,每添加一個,數組長度爲原來的長度+1,將原數組內容拷貝到新數組中。windows

VirtualMachine.attach

進入AttachProvider.providers(),這裏面會初始化AttachProvider,並返回一個AttachProvider List數組

進入ServiceLoader.load(AttachProvider.class, AttachProvider.class.getClassLoader());微信

繼續跟進方法 new LazyIterator(service, loader) ide

看一下com.sun.tools jar包下的META-INF/services/目錄,打開 com.sun.tools.attach.spi.AttachProvider, 能夠看到有不一樣平臺操做系統的實現,個人是windows,會調用windos的實現sun.tools.attach.WindowsAttachProvider。其餘的都被註釋掉了。代碼看到這,就知道ServiceLoader.load方法最終加載的是sun.tools.attach.WindowsAttachProvider源碼分析

上文hasNextService()方法下面的nextService()spa

回到最初的VirtualMachine.attach(String var0)方法,進入return var4.attachVirtualMachine(var0);attachVirtualMachine()操作系統

經過 ClassLoader 類中的findNative方法,能夠找到JVM源碼中的一些native方法調用名,這樣能夠關聯着JVM源碼看底層的C++源碼到底作了啥設計

發如今attach.dll中找方法名爲Java_sun_tools_attach_WindowsVirtualMachine_openProcessnative method

嘗試性的在jdk源碼裏去找這2個方法Java_sun_tools_attach_WindowsVirtualMachine_openProcessJava_sun_tools_attach_WindowsVirtualMachine_enqueue

virtualMachine.loadAgent()、 virtualMachine.detach()源碼流程和上述相似,也和平臺相關,這裏就不在贅述了。

RedefineClasse配置注意事項

能夠在運行期對已加載類的字節碼作變動,可是這種狀況下會有不少的限制 對比新老類,並要求以下:

  • 父類是同一個
  • 實現的接口數也要相同,而且是相同的接口
  • 類訪問符必須一致
  • 字段數和字段名要一致
  • 新增的方法必須是 private static/final 的
  • 能夠刪除修改方法

參考

JVM 源碼分析之javaagent 原理徹底解讀

點關注,不迷路

文章每週持續更新,能夠微信搜索「 十分鐘學編程 」第一時間閱讀和催更,若是這個文章寫得還不錯,以爲有點東西的話 ~求點贊👍 求關注❤️ 求分享❤️
各位的支持和承認,就是我創做的最大動力,咱們下篇文章見!

相關文章
相關標籤/搜索