简介

上一篇文章我们讲解了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的博客

欢迎关注我的公众号:程序那些事,更多精彩等着您!

JVM系列之:JIT中的Virtual Call接口的更多相关文章

  1. JVM系列之:JIT中的Virtual Call

    目录 简介 Virtual Call和它的本质 Virtual Call和classic call Virtual Call优化单实现方法的例子 Virtual Call优化多实现方法的例子 总结 简 ...

  2. 小师妹学JVM之:JIT中的PrintCompilation

    目录 简介 PrintCompilation 分析PrintCompilation的结果 总结 简介 上篇文章我们讲到了JIT中的LogCompilation,将编译的日志都收集起来,存到日志文件里面 ...

  3. 小师妹学JVM之:JIT中的PrintAssembly

    目录 简介 使用PrintAssembly 输出过滤 总结 简介 想不想了解JVM最最底层的运行机制?想不想从本质上理解java代码的执行过程?想不想对你的代码进行进一步的优化和性能提升? 如果你的回 ...

  4. JVM系列五:JVM监测&工具

    JVM系列五:JVM监测&工具[整理中]  http://www.cnblogs.com/redcreen/archive/2011/05/09/2040977.html 前几篇篇文章介绍了介 ...

  5. jvm系列(八):jvm知识点总览-高级Java工程师面试必备

    在江湖中要练就绝世武功必须内外兼备,精妙的招式和深厚的内功,武功的基础是内功.对于武功低(就像江南七怪)的人,招式更重要,因为他们不能靠内功直接去伤人,只能靠招式,利刃上优势来取胜了,但是练到高手之后 ...

  6. jvm系列(四):jvm知识点总结

    原文链接:http://www.cnblogs.com/ityouknow/p/6482464.html jvm 总体梳理 jvm体系总体分四大块: 类的加载机制 jvm内存结构 GC算法 垃圾回收 ...

  7. jvm系列四、jvm知识点总结

    原文链接:http://www.cnblogs.com/ityouknow/p/6482464.html jvm 总体梳理 jvm体系总体分四大块: 类的加载机制 jvm内存结构 GC算法 垃圾回收 ...

  8. jvm系列(八):jvm知识点总览

    在江湖中要练就绝世武功必须内外兼备,精妙的招式和深厚的内功,武功的基础是内功.对于武功低(就像江南七怪)的人,招式更重要,因为他们不能靠内功直接去伤人,只能靠招式,利刃上优势来取胜了,但是练到高手之后 ...

  9. JVM系列文章(四):类载入机制

    作为一个程序猿,只知道怎么用是远远不够的. 起码,你须要知道为什么能够这么用.即我们所谓底层的东西. 那究竟什么是底层呢?我认为这不能一概而论.以我如今的知识水平而言:对于Web开发人员,TCP/IP ...

随机推荐

  1. SQLserver , MySQL的区别和各自的一些简单方法案列

    SQL Server数据库和MySQL数据库有什么区别呢?今天我们来分析一下这两种数据库的不同之处以及这两种数据库的一些简单用途:SQL Server数据库和MySQL数据库有什么区别: 对于程序开发 ...

  2. 从零搭建Spring Cloud Gateway网关(三)——报文结构转换

    背景 作为网关,有些时候可能报文的结构并不符合前端或者某些服务的需求,或者因为某些原因,其他服务修改报文结构特别麻烦.或者需要修改的地方特别多,这个时候就需要走网关单独转换一次. 实现 话不多说,直接 ...

  3. 【五学x红小豆xRS】两边三地大联动-句型

    <第五共和国> Tohara LY Sara'm, Sabang Chua Setuk KS Kareh Moh Induree Junchi Chueh? 阁下!和这样的虫豸在一起,怎么 ...

  4. C#中的char和string的使用简介

    char 字符 char代表一个Unicode字符,它是System.Char的别名 char someChar = 'a';//定义了一个字符 char newLine= '\n';//这是一个换行 ...

  5. 利用宝塔和rainloop搭建咱的邮箱

    需要咱准备的东东:一枚域名.服务器需根据情况开放25.110.143.465.993端口.宝塔邮局管理器.rainloop.LNMP或者LAMP. 搭建步骤: 1.安装宝塔邮局管理器: 2.设置宝塔邮 ...

  6. python基础--深浅copy(重点)

    在此申明一下,博客参照了https://www.cnblogs.com/jin-xin/,自己做了部分的改动 深浅copy(重点) 先问问大家,什么是拷贝?拷贝是音译的词,其实他是从copy这个英文单 ...

  7. 第三章 Java面向对象(下)

    3.1.抽象类 概述:在做子类共性功能抽取时,有些方法在父类中并没有具体的体现,这个时候就需要抽象类了 格式:public abstract class 类名 {} 语法特点: 抽象类和抽象方法必须使 ...

  8. 02_HTML03

    学于黑马和传智播客联合做的教学项目 感谢 黑马官网 传智播客官网 微信搜索"艺术行者",关注并回复关键词"软件测试"获取视频和教程资料! b站在线视频 HTML ...

  9. dubbo泛化调用 小demo

    前两天刚好有个同事来问是否用过 dubbo泛化 调用,不需要通过指定配置.第一次听到的时候,还是有点懵,但觉得有意思,可以学点东西. 立马百度了,找了demo,这篇比较容易上手(http://www. ...

  10. three.js之初探骨骼动画

    今后的几篇郭先生主要说说three.js骨骼动画.three.js骨骼动画十分有意思,但是对于初学者来说,学起来要稍微困难一些,官方文档比较少,网上除了用圆柱体的例子就是引用外部模型的,想要熟练使用骨 ...