• java虚拟机结构


    第二章java虚拟机结构

    本规范描述的是一种抽象化的虚拟机的行为,而不是任何一种被广泛使用的虚拟机实现

    1.Class文件格式

    编译后被Java虚拟机所执行的代码使用了一种平台中立的二进制格式来表示,并且经常(但并非绝对)以文件的形式存储,因此这种格式被称为Class文件格式。Class文件格式中精确地定义了类与接口的表示形式,包括在平台相关的目标文件格式中一些细节上的惯例

    所以说按字节读取class文件,然后再根据规范去理解,就一定不会出错

    2.数据类型

    种类:原始类型和引用类型

    作用:变量赋值、参数传递、方法返回和运算操作

    区别:原始类型的值不需要通过特殊标记或别的额外识别手段来在运行期确定它们的实际数据类型,也无需刻意将它们与引用类型的值区分开来,虚拟机的字节码指令本身就可以确定它的指令操作数的类型是什么,所以可以利用这种特性即可直接确定操作数的数值类型。

    其他:编译器应当在编译期间尽最大努力完成可能的类型检查,使得虚拟机在运行期间无需进行这些操作

    2.1原始类型与值

    种类:数值(整数,浮点),布尔,returnAddress

    boolean:编译后为int/type

    returnAddress:finally相关,忘记它

    原生类型的值都是数字嘛,其中浮点型和char比较特殊

    1.float表示范围为什么比int大?

    参照  IEEE 754  规范 

    2.整数内容的提升?

    数值内容的提升

    3.char类型的转换

    2.2引用类型与值

    种类:类类型(Class Types)、数组类型(Array Types)和接口类型(Interface Types)

    这些引用类型的值分别由类实例、数组实例和实现了某个接口的类实例或数组实例动态创建。

    引用类型的默认值就是null

    Java虚拟机规范并没有规定null在虚拟机实现中应当怎样编码表示

    这说的不就是对象嘛

    3.运行时数据区

    PC寄存器:每天线程都有的程序计数器

    Java虚拟机栈(java栈):用以存放栈帧

    :共享区域,也是供所有类实例和数组对象分配内存的区域,被垃圾收集器强制管理(传说中的垃圾堆- -)

    方法区:共享区域,存储了每一个类的结构信息,方法区是堆的逻辑组成部分,但gc不强制处理

    运行时常量池:运行时常量池是每一个类或接口的常量池的运行时表示形式

    本地方法栈:有了它算是平台依赖了,而且也不强制要求实现

    可以看到每个区域的担任的任务是不一样的,栈看起来应该是一个容器,类似于数组

    什么是堆和栈?

    看书多了就觉得堆跟栈总是重名,是命名的原因还是翻译有问题有机会的看看

    首先数据结构中有堆跟栈,其中

    :满足一定性质的完全二叉树(二叉树中任一非叶子结点关键字的值均小于(大于)它的孩子结点的关键字)

    栈(堆栈):是限制仅在表的一端进行插入和删除运算的线性表。有顺序栈、链式栈(先进后出)

    :只允许在一端进行插入,而在另一端进行删除的运算受限的线性表(先进先出)

    栈和队列是两种特殊的线性表,它们的逻辑结构和线性表相同,只是其运算规则较线性表有更多的限制,故又称它们为运算受限的线性表。

    结构只是理论,实际上我们也不怎么用,在java中的实现类没找到- -

    而在操作系统中

    堆栈是对内存操作的一种机制,可以度娘下 操作系统对内存的管理

    所以可以看到jvm既然成为虚拟机,就一定会有对内存的管理机制,将这个名字继承下来就是Java虚拟机栈和堆,但他终究是虚拟机,是由其他程序编写出来的,所以Java虚拟机栈还是存在计算机堆中的(或许这样就可以解释为什么这个栈可拓展了吧)

    2.1栈帧

    栈帧是用来存储数据和部分过程结果的数据结构,同时也被用来处理动态链接、方法返回值和异常分派

    栈帧随着方法调用而创建,随着方法结束而销毁——无论方法是正常完成还是异常完成(抛出了在方法内未被捕获的异常)都算作方法结束。栈帧的存储空间分配在Java虚拟机栈之中,每一个栈帧都有自己的局部变量表、操作数栈和指向当前方法所属的类的运行时常量池的引用

    jvm栈中放的都是栈帧,栈帧具有3个属性,且栈帧是私有的,在一个栈针中无法调用其他栈针的值

    局部变量表

    每个栈帧内部都包含一组称为局部变量表的变量列表。栈帧中局部变量表的长度由编译期决定

    一个局部变量可以保存一个类型为boolean、byte、char、short、float、reference和returnAddress的数据,两个局部变量可以保存一个类型为long和double的数据。

    Java虚拟机使用局部变量表来完成方法调用时的参数传递,当一个方法被调用的时候,它的参数将会传递至从0开始的连续的局部变量表位置上。特别地,当一个实例方法被调用的时候,第0个局部变量一定是用来存储被调用的实例方法所在的对象的引用(即Java语言中的“this”关键字)。后续的其他参数将会传递至从1开始的连续的局部变量表位置上

    那么,

    long和double为什么特殊?对jvm的识别有什么样的影响?

    不知道

    操作数栈

    每一个栈帧内部都包含一个称为操作数栈的后进先出栈    

    Java虚拟机的解释执行引擎被称为"基于栈的执行引擎",虚拟机把操作数栈作为它的工作区——大多数指令都要从这里弹出数据,执行运算,然后把结果压回操作数栈。

    动态链接

    在Class文件里面,描述一个方法调用了其他方法,或者访问其成员变量是通过符号引用来表示的,动态链接的作用就是将这些符号引用所表示的方法转换为实际方法的直接引用。类加载的过程中将要解析掉尚未被解析的符号引用,并且将变量访问转化为访问这些变量的存储结构所在的运行时内存位置的正确偏移量。

    2.2对象

    Java虚拟机规范不强制规定对象的内部结构应当如何表示。

    总结:class文件存在jvm中的“样式”(结构)

  • 相关阅读:
    koa2 ctx.body 在 mysql query的回调函数中无法赋值的问题
    hibernate 实现多表连接查询
    Struts2 的国际化实现
    struts2 dwr There is no Action mapped for action ... 原因及解决方案
    Hibernate4.1配置数据库连接池 org.hibernate.service.jndi.JndiException:Unable to lookup JNDI name java:comp/env...
    Android 使用JSON格式与服务器交互 中文乱码问题解决
    Struts2 访问 Servlet API 的三种方法
    Struts2 输入校验
    hibernate4 和 spring3 整合注意事项 否则java.lang.NoSuchMethodError异常
    MySQL密码忘记的解决方案
  • 原文地址:https://www.cnblogs.com/liuCy/p/3525418.html
Copyright © 2020-2023  润新知