文档章节

虚拟机字节码执行引擎

偶尔诗文
 偶尔诗文
发布于 2017/04/04 11:51
字数 1121
阅读 18
收藏 0
  1. java程序运行时候栈帧结构

        

  • 栈帧:虚拟机栈的元素,是进行方法调用和方法执行的数据结构,栈帧存储了方法的局部变量表,操作数栈,动态连接,方法的返回地址。
  • 栈顾名思义,指的就是它的数据结构,这种数据结构的特点就是后进先出,因此只有位于栈顶的栈帧才是有效的,成为当前栈,与这个栈帧相关联的方法成为当前方法。

    2.栈帧简介

       栈帧主要包括局部变量表,操作数栈,动态链接,方法返回地址等信息,下面一一为大家介绍

  • 局部变量表

        用于存放方法参数和方法内定义的局部变量,容量以变量槽(slot)为最小单位,一个slot可以存放32位以内的数据结构;因此像double,long这种数据类型应该用两个连续的slot存储。slot第0位索引默认是传递方法所属对象实例引用;为了节省栈帧空间,slot是可以被重用的

  • 操作数栈

        是先入后出的数据结构,相当于一个用于计算的临时存储局部变量的容器,例如代码 a+b, 则会将a压入操作数栈,b压入操作数栈,再将b拿出来,将a拿出来,计算,再将计算结果压入栈。

  • 动态链接

        每个栈帧都包含一个指向运行时常量池中该栈帧的所属方法的引用

  • 方法返回地址

        方法返回之后会做什么呢?首先恢复上层方法的局部变量表和操作数栈,把返回值(如果有的话)压入调用者栈帧的操作数栈中,调整PC计数器的值以指向方法调用后指令后面的一条指令等。

 

    3.方法的调用

  • 解析

        在类加载阶段,会将加载的class文件里面常量池的一部分符号引用解析为直接引用,这种解析能成立的前提就是:方法在程序真正运行之前就有一个可以确定的版本,并且这个版本在运行期是不可用的,符合这类条件的方法有(静态方法,私有方法,实例构造器,父类方法)

  • 分派

        (1)静态分派

                所有依赖静态类型来定位方法执行版本的分派动作称为静态分派,典型应用就是方法重载,静态分派发生在编译阶段

                那么什么时候静态类型呢?举个例子:

public class OverLoad {

    static abstract class Human{

    }


    static class Man extends Human{

    }

    static class Woman extends Human{

    }

    public void sayHello(Human human){
        System.out.println("人类");
    }

    public void sayHello(Man man){
        System.out.println("男人");
    }

    public void sayHello(Woman woman){
        System.out.println("女人");
    }


    public static void main(String[] args) {
        Human man = new Man();
        Human woman = new Woman();
        OverLoad overLoad = new OverLoad();
        overLoad.sayHello(man);
        overLoad.sayHello(woman);
    }
}
结果:
人类
人类

这里面 Human woman = new Woman();Human就是静态类型,Woman就是实际类型,重载的时候就是根据静态类型来决定使用哪一个方法版本的。

    (2)动态分派

            所谓动态分配就是在程序运行期间才决定调用哪个方法版本,并且是按照实际类型调用,java中最好的体现就是重写。动态分派是不会介意方法参数传进来的是个啥,只会关注方法的调用者是个啥。

    (3)单分派与多分派

            方法的接收者和方法的参数统称为方法的宗量,单分派是根据一个宗量来选择方法版本,多分派是根据多于一个宗量决定方法版本。 

            java是静态多分派,动态但分派的语言。

    4.基于栈的指令集架构与基于寄存器的指令集架构

        指令集架构执行架构主流的一般分为两类,(1)基于栈的指令集架构  (2)基于寄存器的指令集架构,jvm采用的是基于栈的指令集架构。

        基于栈的指令集架构优点如下:

  • 很好的可移植性
  • 编译器实现简单        

        缺点也是有的,那就是跟基于寄存器的指令集架构相比,速度慢一些

        

 

 

 

 

 

 

 

 

© 著作权归作者所有

偶尔诗文
粉丝 12
博文 145
码字总数 63966
作品 0
沈阳
高级程序员
私信 提问
凭啥Java的运行环境称虚拟机,Python的只能称解释器

看到Stackoverflow上有个问题在讨论Java和Python的对比,其中就有人问答为啥Java的运行环境被称之为JVM,而Python的只能叫做Interpreter。 这个问题估计想过的人不多,先找维基百科看一下虚拟...

AlexMahoneFBI
2015/03/07
324
0
java虚拟机中常见名词概念-深入理解jvm

一:java虚拟机的体系结构图: jvm :中文名称叫Java虚拟机,它是由软件技术模拟出计算机运行的一个虚拟的计算机。我们都知道Java的程序需要经过编译后,产生.Class文件,JVM才能识别并运行它...

Swen_9826
2018/08/08
0
0
【JVM系列】一步步解析java执行内幕

对于任何一门语言,要想达到精通的水平,研究它的执行原理(或者叫底层机制)不失为一种良好的方式。在本篇文章中,将重点研究java源代码的执行原理,即从程 序员编写JAVA源代码,到最终形成产...

java菜分享
03/02
0
0
[虚拟机字节码执行引擎] 1 - 栈桢

本文主要内容 前言 运行时栈桢结构 已经学习了虚拟机内存区域、Class文件结构、类加载机制等知识,是时候学习虚拟机字节码执行过程了。 前言 虚拟机是一个相对物理机而言的概念,它们都有代码...

某昆
2018/01/06
0
0
一个“Hello World”理解JVM运行时数据区

先上一张JVM体系结构图: 1)运行时数据区:经过编译生成的字节码文件(class文件),由class loader(类加载子系统)加载后交给执行引擎执行。在执行引擎执行的过程中产生的数据会存储在一块内...

ntchan
2018/07/12
0
0

没有更多内容

加载失败,请刷新页面

加载更多

URL/URI/URN的认识

这两天在写代码的时候,由于涉及到资源的位置,因此,需要在Java Bean中定义一些字段,用来表示资源的位置,比如:imgUrl,logoUri等等。但是,每次定义的时候,心里都很纠结,是该用imgUrl还...

WinkJie
23分钟前
2
0
vs2017 踩坑

好久没有使用vs2017,改了下代码,启动调试进行测试,一没有注意,就启动了。 然后 ,悲剧了,,,就有下面的问题。 VS断点提示:当前不会命中断点。还没有为该文档加载任何符号 然后百度了下,...

轻轻的走过
23分钟前
3
0
解决一个emqttd trace 无法打开的问题

emqttd这个东西做的真心不咋地,之前有emq_auth_mysql的plugin死活无法启动的问题,现在又碰到trace无法打开的问题。 查看emqttd服务器当前连接的所有client: emqttd_ctl clients list 要打...

莫在全
31分钟前
3
0
java wsdl 中不显示参数属性类型的问题解决方案

CXF3.0.1解决方案: 配合spring方式 <jaxws:endpoint id="receiveUMSMessageService" implementor="com.sw.extInterface.webservice.service.impl.ReceiveUMSMessageServiceImpl" address="......

嘿嘿嘿IT
34分钟前
2
0
go alpine docker image 搭建

Dockerfile 搭建 目录结构 --Dockerfile--main.go 写一个go的helloworld package mainimport ("fmt""log""net/http")func main() {http.HandleFunc("/", hello)err := ht......

solate
40分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部