深圳Java培训
达内深圳宝安中心

136-3244-2201

热门课程

【达内JAVA学堂】Java字节码指令的执行

  • 时间:2015-10-21
  • 发布:深圳达内
  • 来源:深圳达内

程序调用的是不同实际类型的同名方法,虚拟机依据对象的实际类型去寻找是否有这个方法,作为Java开发人员,一定程度了解JVM虚拟机的的运作方式非常重要,深圳达内JAVA培训就一些简单的虚拟机的相关概念和运作机制展开我自己的学习过程,虚拟机运行活化的内存数据中的指令:程序的执行。

【达内JAVA学堂】Java字节码指令的执行

前面我们说明了java源码被编译成为了二进制字节码,二进制字节码转为内存中方法区里存储的活化对象,那么最重要的程序执行就做好了基础:当方法区里的字段和方法按照虚拟机规定的数据结构排好,常量池中的符号引用数据在加载过程中最大限度地转为了直接引用,那么这个时候虚拟机就可以在加载主类后创建新的线程按步执行主类的main函数中的指令了。

java虚拟机执行程序的基础是特定的二进制指令集和运行时栈帧:

二进制指令集是java虚拟机规定的一些指令,在编译后二进制字节码的类方法里的字节码就是这种指令,所以只要找到方法区里的类方法就可以依照这套指令集去执行命令。

运行时栈帧是虚拟机执行的物理所在,在这个栈帧结构上,方法的局部变量、操作数栈、动态链接和返回地址依序排列,依照命令动态变换栈帧上的数据,最终完成所有的这个方法上的指令。

栈帧的进一步划分:

局部变量表:包括方法的参数和方法体内部的局部变量都会存在这个表中。

操作数栈:操作数栈是一个运行中间产生的操作数构成的栈,这个栈的栈顶保存的就是当前活跃的操作数。

动态链接:我们之前提到这个方法中调用的方法和类在常量池中的符号引用转换为的直接引用就保存在这里,只要访问到这些方法和类的时候就会根据动态链接去直接引用所指的地址加载那些方法。

返回地址:程序正常结束恢复上一个栈帧的状态的时候需要知道上一个指令的地址。

这个过程是从固化在class文件中的二进制字节码开始,经过加载器对当前类的加载,虚拟机对二进制码的验证、准备和一定的解析,进入内存中的方法区,常量池中的符号引用一定程度上转换为直接引用,使得字节码通过结构化的组织让虚拟机了解类的每一块的构成,创建的线程申请到了虚拟机栈中的空间构造出属于这一线程的栈帧空间,执行主类的main方法。

首先检查main的访问标志、描述符描述的返回类型和参数列表,确定可以访问后进入Code属性表执行命令,读入栈深度建立符合要求的操作数栈,读入局部变量大小建立符合要求的局部变量表,根据参数数向局部变量表中依序加入参数(第一个参数是引用当前对象的this,所以空参数列表的参数数也是1),然后开始根据命令正式执行。

我们可以看出来无论是重载还是重写,都是二进制指令invokevirtual调用了sayHello方法来执行的。

在重载中,程序调用的是参数实际类型不同的方法,但是虚拟机最终分派了相同外观类型(静态类型)的方法,这说明在重载的过程中虚拟机在运行的时候是只看参数的外观类型(静态类型)的,而这个外观类型(静态类型)是在编译的时候就已经确定的,和虚拟机没有关系。这种依赖静态类型来做方法的分配叫做静态分派。

在重写中,程序调用的是不同实际类型的同名方法,虚拟机依据对象的实际类型去寻找是否有这个方法,如果有就执行,如果没有去父类里找,最终在实际类型里找到了这个方法,所以最终是在运行期动态分派了方法。在编译的时候我们可以看到字节码指示的方法都是一样的符号引用,但是运行期虚拟机能够根据实际类型去确定出真正需要的直接引用。这种依赖实际类型来做方法的分配叫做动态分派。得益于java虚拟机的动态分派会在分派前确定对象的实际类型,面向对象的多态性才能体现出来。

【更多JAVA资讯JAVA培训新闻请关注深圳JAVA培训sz.java.tedu.cn】    

上一篇:中信网络科技到深圳达内招聘Java工程师
下一篇:JAVA为什么使用动态代理?

预计发布的Java 9中,很令人期待的是什么?

【深圳JAVA培训】世界十类很急需IT人才

JAVA——很吃香的编程语言

为什么程序员是很有钱的一批人?

选择城市和中心
贵州省

广西省

海南省