簡介
上一篇文章我們講解了Virtual Call的定義并舉例分析了Virtual Call在父類和子類中的優化。
JIT對類可以進行優化,那麼對于interface可不可以做同樣的優化麼?
一起來看看吧。
最常用的接口List
List應該是大家最最常用的接口了,我想這個大家應該不會反駁。
public interface List<E> extends Collection<E> {
今天我們就拿List來做例子,體驗一下JIT優化接口的奧秘。
還是上代碼,要分析的代碼如下:
public class TestVirtualListCall {
public static void main(String[] args) throws InterruptedException {
List<String> list=new ArrayList<>();
for (int i = 0; i < 10000; i++)
{
doWithVMethod(list);
}
Thread.sleep(1000);
}
public static void doWithVMethod(List<String> list)
{
list.add("www.flydean.com");
}
}
如果在指令行運作,大家記得在運作時添加參數-XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:-Inline
直接看JIT Watcher的結果:
我們可以看到JIT中先對ArrayList的實作類做了一個比較。
然後調用的是invokeinterface,但是其本質還是invokevirtual,并且我們可以看到這個調用是被優化過了:optimized virtual call。
多個List的調用
同樣的,我們可以測試一下多個list子類的情況下怎麼調用:
public class TestVirtualListCall2 {
public static void main(String[] args) throws InterruptedException {
List<String>[] lists=new List[]{new ArrayList<>(),new LinkedList<>()};
for (int i = 0; i < 10000; i++)
{
doWithVMethod(lists[i%2]);
}
Thread.sleep(1000);
}
public static void doWithVMethod(List<String> list)
{
list.add("www.flydean.com");
}
}
同樣,使用JIT Watcher來運作:
我們可以看到JIT做了兩次對象類型的比較,然後對兩個invokeinterface都做了優化。
結果和我們的父類子類結果是一樣的。
不一樣的List調用
上面我們在做多個list調用的時候,是輪循着來調用的,如果我們先調用ArrayList的方法,再調用LinkedList的方法,會有什麼不同呢?
一起來看看。
public class TestVirtualListCall3 {
public static void main(String[] args) throws InterruptedException {
List<String> list1 = new ArrayList<>();
List<String> list2 = new LinkedList<>();
for (int i = 0; i < 10000; i++)
{
doWithVMethod(list1);
}
Thread.sleep(1000);
for (int i = 0; i < 10000; i++)
{
doWithVMethod(list2);
}
Thread.sleep(1000);
}
public static void doWithVMethod(List<String> list)
{
list.add("www.flydean.com");
}
}
上面我們先循環ArrayList,然後再循環LinkedList。
看下結果有什麼不同:
可以看到,JIT先比較了ArrayList,然後隻做了一次方法的優化。
也就是說LinkedList的調用是沒有進行代碼優化的。
上面的結果是在C2編譯器下,也就是level4的編譯水準下解析的。
我們看下如果在C1編譯器下,也就是Level3編譯水準下有什麼不同。
可以看到C1編譯下,所有的invokeinterface都沒有進行編譯優化,隻有在C2編譯下,才會進行優化。
不同的JVM版本可能優化方式不一樣。大家可以自行實驗。
總結
本文用執行個體展示了Virtual Call在interface上面的優化使用。
感興趣的朋友,可以一起讨論。
本文作者:flydean程式那些事
本文連結:
http://www.flydean.com/jvm-virtual-call-interface/本文來源:flydean的部落格
歡迎關注我的公衆号:程式那些事,更多精彩等着您!