java tostring方法_Java虚拟机如执行方法调用的(二)?

3ccbde4e245bbbe892ab215e7d723e7e.png

虚方法调用

Java里所有非私有实例方法调用都会被编译成invokevirtual指令.
接口方法调用都会被编译成invokeinterface指令.这两种指令都属于Java虚方法的调用.

在大多数情况下, Java虚拟机需要根据调用者的动态类型, 来确定虚方法调用的目标方法.这个过程被称为动态绑定. 那么相对于静态绑定的非虚方法调用来说, 虚方法调用更加耗时.

在Java虚拟机中, 静态绑定包括:

  • 调用静态方法的invokestatic指令.
  • 调用构造器、私有实例方法及超类非私有实例方法的invokespecial指令.
  • 如果虚方法调用指向一个被标记为final的方法,那么Java虚拟机也可以静态绑定该虚方法调用的目标方法.

Java虚拟机采用了一种用空间换时间的策略来实现动态绑定.

它为每个类生成一张「方法表」,有以快速定位目标方法.

方法表

在类加载准备阶段, 它除了为静态字段分配内存之外, 还会构造与类相关联的「方法表」.

这个数据结构, 是Java虚拟机实现动态绑定的关键.

方法表本质上是一个数组,每个数组元素指向一个当前类及其祖先类中非私有的实例方法.

这些方法可能是具体的、可执行的方法,也可能是没有相应字节码的「抽象方法」.

「方法表」满足两个特性:

  • 子类方法表中包含父类方法表中所有的方法.
  • 子类方法在方法表中的索引值, 与它所重写父类方法的索引值相同.
方法调用指令中的「符号引用」会在执行之前「解析成实际引用」. 对于静态绑定的方法而言, 「实际引用」将指向「具体的目标方法」. 对于「动态绑定」的方法调用而言, 「实际引用」则是「方法表的索引值」(实际上并不仅仅是索引值).

在执行过程中, Java虚拟机将获取调用者的实际类型, 并在该实际类型的「方法表」中, 根据「索引值」获取目标方法. 这个过程就是「动态绑定」

「示例」

// 定义一个抽象的动物类. 

上面简单的示例中, 各个类的「方法表」分别是:

106de6cae456bd7635764ab8c885a808.png
各个类的方法表

在示例当中, 「Animal类」的方法表包括两个方法:

  • toString()
  • eat()

它们分别对应0号和1号.

之所以方法表调换了toString()和eat()方法的位置, 是因为toString()方法的「索引值」需要与「Object」类中同名的方法的「索引值」一致. (为了保持简洁, 暂时不考虑Object类中的其它方法).

「Dog」类的方法表同样也包括两个方法. 其中, 0号方法指向「继承」而来的toString()方法. 1号方法则指向自己重写的「eat」方法.

「Cat」类的方法表中包括3个方法, 除了继承而来的「Animal」类的toString()方法, 自己重写的「eat」方法之外, 还包括独立的「sleep」方法.

测试代码的执行过程可以这么理解, 可以把「Java虚拟机」理解与一个饲养员, 每当过来一个动物, 饲养员先看看是啥东西(获取动态类型), 然后翻出狗/猫对应的饲养手册(获取动态类型的方法表). 手册的第1条则显示动物如何吃东西的方法(用1作为索引来查找方法表对应的目标方法).

实际上, 使用了「方法表」「动态绑定」「静态绑定」相比. 仅仅是多出了几个「内存 解引用操作」.访问栈上的调用者, 获取调用者的动态类型, 读取该类型的方法表, 读取该方法表中的某个索引值所对应的目标方法.
相对于创建并初始化Java栈帧来说, 这几个解引用操作简直可以忽略不计.

1f7f352cfd24792747c6232d0f89f4e0.png
动态绑定获取目标方法
「虚方法」优化的效果看上去十分美好, 但实际上仅存大于「解释执行」中, 或者「即时编译」代码的最坏情况中.

这是因为「即时编译」还拥有另外两种性能更好的优化手段: 「内联缓存(inlining cache)」和「方法内联(method inlining)」. 先说第一种「内联缓存」.

内联缓存

「内联缓存」是一种加快「动态绑定」的优化技术.

它能够「缓存虚方法调用中调用者的动态类型, 以及该类型所对应的目标方法」 . 在之后的执行过程中, 如果碰到已「缓存」的类型, 「内联缓存」便会直接调用该类型所对应的「目标方法」. 如果没有碰到已缓存的类型, 「内联缓存」则会退化至使用「基本方法表的动态绑定」.

ce9f4b59feecd80df59efa825cc10f65.png
内联缓存查找目标方法

在针对多态的优化手段中, 通常会提及以下三个术语.

  1. 单态(monomorphic)
    1. 指的是「仅有一种状态」的情况
  2. 多态(polymorphic)
    1. 批的是「有限数量种状态」的情况.
  3. 超多态(megamorphic)
    1. 批的是「更多种状态」的情况.
通常我们用一个「具体数值」来区分「多态」和「超多态」. 在这个数值之下, 我们称为「多态」. 反之,则称为「超多态」.

对于「内联缓存」来说, 我们也对应的「单态内联缓存」、「多态内联缓存」、「超多态内联缓存」.

「单态内存缓存」, 就是只「缓存」一种动态类型以及它所「对应的目标方法」.

实现: 比较所「缓存的动态类型」, 如果命中, 则「直接调用对应的目标方法」.

「多态内联缓存」则缓存了多个动态类型及其「目标方法」.

实现: 它需要逐个将所「缓存」的「动态类型」与「当前动态类型」进行比较, 如果命中, 则调用「对应的目标方法」.

一般来说, 会将「更加热门的动态类型」放在「前面」. 在实践中, 大部分的「虚方法」调用均是「单态」的, 也就是只有一种「动态类型」.

为了节省内存空间,Java虚拟机只采用「单态内联缓存」.

前面所说的, 当「内联缓存」没有命中的情况下, Java虚拟机需要「重新使用方法表进行动态绑定」. 对于「内联缓存」中的内容, 我们有两种选择.

  1. 「替换单态内联缓存中的记录」
这种做法, 对数据的局部性有要求, 即在「替换内联缓存」之后的一段时间内, 方法调用的调用者的动态类型应该保持一致, 从而能够有效的复用「内联缓存」. 在最坏的情况下, 用两种不同类型的「调用者」, 轮流执行该方法调用, 那么每次进行方法调用都将替换「内联缓存」. 也就是说, 只有写缓存的额外开销, 而没有用缓存的性能提升.

599d062a05565d5304954c45c766c64e.png
替换单态内存内联缓存中的记录

2. 「劣化为超多态状态」

这也是Java虚拟机的具体实现方式. 处于这种状态下的「内联缓存」,实际上放弃了优化的机会.

它将直接访问「方法表」, 来「动态绑定目标方法」.

与「替换内联缓存记录」的做法相比, 它牺牲了优化的机会, 但是「节省了写缓存的额外开销」.

虽然「内联缓存」随带「内联」二字, 但是它并没有「内联目标方法」.

这里需要明确的是, 任何方法调用除非被内联, 否则都会固定开销.这些开销来源于「保存程序在该方法中的执行位置、新建、压入和弹出新方法所使用的栈 帧」. 对于极其简单的方法而言, 比如说getter/setter, 这部分「固定开销」占据的CPU时间甚至超过了方法本身. 此外, 在「即时编译」中, 「方法内联」不仅仅能够消除方法「调用的固定开销」, 而且还增加了进一步优化的可能性.

本篇完...

谢谢观看 ~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/490127.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[笔记]cin、cout与scanf、printf的效率差异对比分析

之前上传UVa227 puzzle时,好不容易AC了,但发现自己用时50(ms),而在VJ上看到人家都是40ms、20ms,于是打开一个20ms的代码查看人家强在哪里。但结果研究了半天感觉差不多,于是想着应该不是算法的问题。然后又想到&#x…

“智联网与未来”——第14届中国信息技术年会院士精彩观点辑录

来源:科技导报编者按 以智慧互联为目标的智联网系统是未来信息网络的发展方向,将引发人类社会向智慧社会的重大变革。在中国电子学会、工业和信息化部电子科学技术委员会等主办的第14届中国信息技术年会上,学者热议“智联网与未来”&#xf…

什么是java的元数据_学习大数据,为什么要先学习Java?

是新朋友吗?记得先点蓝字关注我哦~今日课程菜单Java全栈开发 | Web前端H5大数据开发 | 数据分析人工智能Python | 人工智能物联网来源:小职(z_zhizuobiao)找我:✅ 解锁高薪工作 ✅ 免费获取干货教程未完待续很多人初学的第一门语言…

记忆的天空:“崩塌型”记忆活动原理

作者:钟振余宁波大学副教授,工科背景,专注于脑科学神经信息活动机制研究。记忆是大脑活动原理的重要研究内容。相对于现代科学的高速发展,人类对于大脑活动原理的了解仍处在初级阶段。差不多半个多世纪之前,意识灵魂论…

飞天智能:阿里云的 AI 落地野心

来源:大叔爱吐槽CSDN当下,AI 业界不会否认的一个事实是,AI实力的比拼不再是单点的算法技术能力,而是从底层算法到应用平台的全面AI能力。单纯的算法,只是实验室里的乐趣,唯有结合商业的数据处理能力和技术变…

oracle把时间段转换成每一天_在家办公难适应?来看看专职外汇交易员的一天

万万没想到,曾经幻想的躺在床上把钱赚,居然成真了!这不,受疫情的影响,不少人在家开工了!今天是主流人群在家办公的第三天,然而,很多人表示:自己依然没有适应在家办公的节…

UVALive 7455 Linear Ecosystem (高斯消元)

Linear Ecosystem题目链接: http://acm.hust.edu.cn/vjudge/contest/127401#problem/B Description http://7xjob4.com1.z0.glb.clouddn.com/99b0fe905e5bd89a24c882832c93cc09 Input The first line of the input file contains an integer, n, which is the numbe…

华为诺亚方舟实验室—推荐系统中的前沿技术研究与落地报告

来源:专知【导读】9月6-7日,2019中国AI开发者大会(AI ProCon 2019) 在北京拉开帷幕。本次大会由新一代人工智能产业技术创新战略联盟(AITISA)指导,鹏城实验室、北京智源人工智能研究院支持&…

u盘锁电脑_程序员用U盘偷公司源码被抓;Rust 语言发布 5 周年

(给技术最前线加星标,每天看技术热点)综合整理:技术最前线(ID:TopITNews)参考:程序员的那些事、开源中国、solidot、cnBeta、腾讯科技等0、程序员用U盘偷公司源码被判刑2018年5月18日18时20分许,温某某在广州三七互娱科…

20幅漫画告诉你未来世界是怎样的

导读:在你心目中的(不太遥远的)未来是什么样的?名为Futurism Cartoons的作者绘制了一系列以“未来”为主题的漫画,其中多幅跟人工智能及你大数据有关,你们来感受一下……来源:大叔爱吐槽0102030…

c++ qt获取电脑的内存_Qt官方示例-TCP客户端/服务器示例

该示例演示了在本地主机上的TCP客户端和服务器是如何通讯的。客户端 绑定信号槽。connect(&tcpClient, &QAbstractSocket::connected, this, &Dialog::startTransfer); /* 连接到服务器时回送消息给服务器 */ connect(&tcpClient, &QIODevice::bytesWritte…

下一个10年,解决问题靠“大脑”

前言:本文是网络智库举办的《崛起的超级智能:互联网大脑如何影响科技未来》新书分享会记录,作者刘锋主讲,深入阐述了科技时代谷歌大脑,百度大脑,阿里大脑,腾讯大脑,城市大脑&#xf…

JavaMail发送邮件

使用javax.mail可以发送普通文本文件,HTML格式的文件,同样可以发送图文并茂(包含附件)的java邮件。 发送邮件需要在验证发送的邮箱和密码:验证的帐号(本人使用163邮件)需要打开POP3/SMTP/IMAP 设置邮箱授权登录密码(已设置好): 新建java项目添…

cf两边黑屏怎么解决win10_关闭自动睡眠仍然睡眠?Win10过几分钟就会自动睡眠黑屏解决方法...

近期有Win10网友遇到一个奇怪的问题,已经设置了关闭了睡眠,也设置了从不关闭显示器,但是大概2分钟-3分钟不动鼠标或者对电脑无操作的时候,电脑就会出现自动睡眠黑屏的情况,网友根据网上的解决这个问题相关帖子进行操作…

Word如何固定页面内容在某一页开头

在写论文时经常需要新起一页从第一行写新的一章,那么如何固定这一页的内容是从这一页第一行开始写的呢? 例如需要将参考文献放在新的一页中开始写,那么在上一页的最后位置插入“分隔符”→“分页符”即可

西门子plm_好事连连 西门子PLM新品多项合作并举

几乎是同一时间,西门子PLM集中发布了多项重磅解决方案,并与IBM联合推出服务生命周期管理解决方案。西门子与IBM联合推出的服务生命周期管理解决方案,能够将实际维护和资产性能与设计决策和现场修改动态结合,从而优化资产的服务生命…

win10亮度怎么调_笔记本屏幕亮度怎么调

大家好,今天分享一篇来自装机吧官网(zhuangjiba.com)的图文教程。许多网民发现,当他们的计算机在办公室时,计算机屏幕的亮度会变暗,其中一些代表了计算机电量不足的问题,或者存在计算机没有设置亮度的问题。虽然计算机…

小程序下拉刷新_微信小程序下拉刷新

下拉刷新是常用操作,微信已经集成好了(真机效果稍有瑕疵)首先需要在.json文件启用下拉刷新{"enablePullDownRefresh": true, }然后在.js文件,监听下拉操作,处理loading和请求onPullDownRefresh() {wx.showNa…

牛津大学名誉教授Colin Blakemore:大脑是如何计算的?

智慧起航,共创未来【导读】9月21日,英国皇家学会会士、中国工程院外籍院士、香港城市大学教授、牛津大学名誉教授Colin Blakemore在第二届中国认知计算与混合智能学术大会(CCHI2019)作了报告——大脑是如何计算的? Colin教授的主…

表单和iframe的使用

图片热点: 规划出图片上的一个区域,可以做出超链接,直接点击图片区域就可以完成跳转的效果。示例: 网页划区: 在一个网页里,规划出一个区域用来展示另一个网页的内容。示例: 网页的拼接&#xf…