2025-05-23

 

唉~~因為blog總顯示不全隻能分為2個瞭,排版也不是很好,湊合著看吧。

客戶端執行的優化策略有如下3種措施

方法內聯:一個方法的執行離不開其他方法的支持,若調用的其他方法十分簡單。那麼調用的時候會將被調用那個方法裡面所有的內容粘到主調方法中,這樣做的好處是節省參數變量,中間變量的資源和返回值的資源申請位置。

    private void test(){

       test2("1");

    }

  

    private String test2(String a){

       //test2的方法體

       return null;

    }

在JVM編譯中會變成如下方式

    private void test(){

       //test2的方法體

    }

去虛化處理:裝載類的時候會進行類層次的分析,如果發現接口的方法是有一個實現類,那麼JVM會說,別故弄玄虛瞭,就那麼一個實現類,咱將實現類的方法實現內容全粘過來才是實在人,做人要厚道。

接口如下

public interface IA {

    public void t();

}

實現類如下

public class A implements IA {

    public void t(){

       //做你想做的事情

    }

}

下面是一個客戶端調用類

class Demo{

    public void execute(IA ia){

       ia.t();

    }

}

那麼JVM去虛化會將此代碼替換成

class Demo{

    public void execute(IA ia){

       //做你想做的事情

    }

}

冗餘消除:冗餘消除是在編譯期間發現代碼可以進行折疊或者消除。

比如如下代碼

public class A implements IA {

    final static boolean isDebug = false;

    public void t(){

       if(isDebug){

           System.out.println("容我三思");

       }

       System.out.println("全線出擊");

    }

}

反編譯後的class內容如下

import java.io.PrintStream;

 

public class A

  implements IA

{

  static final boolean isDebug = false;

 

  public void t()

  {

    System.out.println("全線出擊");

  }

}

編譯期間可以確定代碼不會執行到“容我三思”的步驟,您隻能“全線出擊”。

服務器模式編譯則比客戶端模式編譯更加費資源,因為編譯器模式的很多優化策略是從整體類運行出發的,主要優化點是標量替換、棧上分配、同步消除三項。這三項優化措施都是基於分析變量是否逃逸的分析結果。這些我們知道有這麼個事情,瞭解一下即可,因為咱們還沒到開發JVM的程度。

3):反射執行:

先回顧一下反射的代碼,再來看看JVM如何處理反射執行的過程的

       Class cls = Class.forName("java.lang.String");

       Object obj = cls.newInstance();

       Method method = cls.getMethod("valueOf", Object.class);

       String str = (String) method.invoke(obj, 1);

       System.out.println(str);

反射調用實際就是動態生成字節碼,並加載到JVM中進行執行。流程如下:先讓調用者所在的ClassLoader來加載創建Class對象,Class對象生出來瞭,之後校驗Class是否為public權限的,如果不是,那麼對不起,反射機制在偉大也不能違反原則,越雷池一步,不是public的類,您還是少碰為妙!之後JVM調用對象的newInstance方法,,該方法先去查找是否有緩存的ConstructorAccessor對象,如果沒有則生成一個。生成ConstructorAccessor的過程需要MethodAccessorGenerator中的generate方法根據Class格式規范生成字節碼,在生成字節碼後,將其加載到ClassLoader中,並實例化完成對象的創建過程。之後就是尋遍方法數組,對照有沒有要使用的”valueOf”方法,如果沒有則拋出異常。如果有,則驗證權限是否能暴露出來供反射調用,所以也是為什麼反射調用執行稍微比直接對象調用方法有點慢的原因瞭。它需要驗證使用權限,還要負責創建Method對象。傳說是現在的JDK版本(Sun JDK1.6.26)在直接調用和反射調用的性能差別不大。這個筆者並沒試過,改天有時間再做測試。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *