亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java類加載器與類的熱替換怎么實現

發布時間:2022-01-14 10:48:02 來源:億速云 閱讀:415 作者:iii 欄目:大數據

這篇文章主要講解了“java類加載器與類的熱替換怎么實現”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“java類加載器與類的熱替換怎么實現”吧!

任何一個使用到的Class,都需要被classLoader加載到JVM中,這個加載的過程,又分為

  1. defineClass

  2. loadClass

  3. resolveClass

即根據提供的不同形式的class文件的內容,轉化成一個Class,對其進行加載,鏈接。

而所謂的hotswap,就是使用新的代碼替換掉已經加載的這個Class中的內容。

我們這里使用Javassist來模擬類似的效果,通過動態的修改class內某個方法的內容,來實現熱替換的效果。

java類加載器與類的熱替換怎么實現

基本步驟:

  1. 先定義一個接口,包含一個方法,該方法內的內容在后面用于熱替換

  2. 定義一個接口的實現

  3. 在Servlet內接收頁面上傳入的參數,頁面上的參數內容,則是具體上面接口定義方法及方法對應的方法體內容

  4. 在接收到參數后,根據參數內容,使用Javassist進行熱替換的操作。

基本Javassist的代碼大概是下面的樣子:

ITemp test = new Temp();  // 聲明一個接口

ClassPool pool = new ClassPool(true);


private ITemp hotswap(String str) {

        String methodBody = null;

        try {

 //添加到classpath

            pool.insertClassPath(new ClassClassPath(ITemp.class));

            String className = "ITemp_" + UUID.randomUUID();


            CtClass clazz = pool.makeClass(className);

            clazz.setInterfaces(new CtClass[]{pool.get("com.xxxx.ITemp")});

            methodBody = str;

            clazz.addMethod(CtMethod.make(methodBody, clazz));


            ITemp fun = (ITemp) clazz.toClass().newInstance();

            calculatorClass.writeFile("d:/temp");

            return fun;


            } catch(Exception e) {

            

            }

在用的過程中,接收到參數后,把hotswap方法返回的實例再指給test這個實例。然后test內對應方法的執行已經改成在頁面上傳入的邏輯。

原理

上面的是怎么樣實現的呢?

其實,上面的替換,實質上,是重新生成了一個ITemp這個接口的實現類,然后我們在頁面上定義的,是這個實現類的方法中的內容。然后我們的替換,是把一個實現類的引用改成另一個。

java類加載器與類的熱替換怎么實現

在更新Server中service的引用,指向新的實現,舊的會在引用請求執行完成后會被釋放。

另外一個

這時,一定有同學提起JDK默認支持的 Agent,這種基于JVMTI的實現。但是,這里需要注意的是,此時使用的是Agent,如果使用其pre_main,那么支持的是Class的 defineClass執行前,對其進行所謂的增強或者是織入,類似于OpenJPA的Enhance和AJP的weave。

這種相當于是把class內容在讀到內容之后修改了一下,然后傳給classLoader進行defineClass。

而JVMTI在JDK1.6之后,支持的另外一種形式,是在應用已經部署啟動之后,要進行類的改變的,使用的是agent_main方法,此時,需要對class進行retransform。像Java里一些常用的Profiler工具使用的就是這種,attach到已經啟動的Java進程,對其進行retransform,例如Btrace。

這里的transform會調用Instrumention的RedefineClass,本質上是修改類的定義。我們以Btrace為例,來看他在背后做了什么。

我的Trace腳本內容如下:

@BTrace(unsafe=true)

public class TracingScript {

@OnMethod(clazz="com.xxx.WorkFun", method="myPrint")

public void sc() {

    println("===========");

  }

}

對于要監控的類WorkFun,我們看到,Btrace監控后,會類內新增一個方法$btrace$TracingScript$sc()

java類加載器與類的熱替換怎么實現

該方法就所做的就是我們在Trace腳本里定義的內容,比如上面,我們會在對應java方法執行時打印一行等號,其對應的方法jvm指令如下:

java類加載器與類的熱替換怎么實現

而這個方法是如何和我們自己要監控的方法聯系起來的呢?就是在我們的監控方法第一行,增加了對于trace方法的調用。

java類加載器與類的熱替換怎么實現

感謝各位的閱讀,以上就是“java類加載器與類的熱替換怎么實現”的內容了,經過本文的學習后,相信大家對java類加載器與類的熱替換怎么實現這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

莱阳市| 拉萨市| 乐昌市| 巴东县| 上栗县| 迭部县| 绥德县| 前郭尔| 治多县| 呼图壁县| 湖北省| 章丘市| 台安县| 陵水| 泸州市| 牙克石市| 库尔勒市| 嘉峪关市| 三亚市| 宜宾市| 漠河县| 富宁县| 泰安市| 梁河县| 杭锦旗| 抚顺市| 祁阳县| 北流市| 汶川县| 娄底市| 喜德县| 开封市| 新密市| 原平市| 响水县| 固阳县| 时尚| 民和| 靖州| 马龙县| 石首市|