虽然这几天 很忙,但是学习是不能落下的,也不能推迟,因为如果推迟了一次,那么就会有无数次;加油,come on!

Java跨平台的基础:

各种不同平台的虚拟机与所有平台都统一使用的程序存储格式——字节码(ByteCode)是构成平台无关性的基石,也是语言无关性的基础。Java虚拟机不和包括Java在内的任何语言绑定,它只与“Class文件”这种特定的二进制文件格式所关联,Class文件中包含了Java虚拟机指令集和符号表以及若干其他辅助信息。

Class类文件结构

Class类的本质

任何一个Class文件都对应着唯一一个类或接口的定义信息,但反过来说,Class文件实际上它并不一定以磁盘文件的形式存在。

Class文件是一组以8位字节为基础单位的二进制流。

Class文件格式

各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。

Class文件格式采用一种类似于C语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:无符号数和表。

无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值。

表是由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表都习惯性地以“_info”结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上就是一张表。

Class格式文件详解

Class的结构不像XML等描述语言,由于它没有任何分隔符号,所以在其中的数据项,无论是顺序还是数量,都是被严格限定的,哪个字节代表什么含义,长度是多少,先后顺序如何,都不允许改变。

按顺序包括:

  魔数与Class文件的版本:

   每个Class文件的头4个字节称为魔数(Magic Number),它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。使用魔数而不是扩展名来进行识别主要是基于安全方面的考虑,因为文件扩展名可以随意地改动。文件格式的制定者可以自由地选择魔数值,只要这个魔数值还没有被广泛采用过同时又不会引起混淆即可。紧接着魔数的4个字节存储的是Class文件的版本号:第5和第6个字节是次版本号(MinorVersion),第7和第8个字节是主版本号(Major Version)。Java的版本号是从45开始的,JDK 1.1之后的每个JDK大版本发布主版本号向上加1高版本的JDK能向下兼容以前版本的Class文件,但不能运行以后版本的Class文件,即使文件格式并未发生任何变化,虚拟机也必须拒绝执行超过其版本号的Class文件。

  常量池:

    常量池中常量的数量是不固定的,所以在常量池的入口需要放置一项u2类型的数据,代表常量池容量计数值(constant_pool_count)。与Java中语言习惯不一样的是,这个容量计数是从1而不是0开始的

    常量池中主要存放两大类常量:字面量(Literal)和符号引用(Symbolic References)。

    字面量比较接近于Java语言层面的常量概念,如文本字符串、声明为final的常量值等。

    而符号引用则属于编译原理方面的概念,包括了下面三类常量:

    类和接口的全限定名(Fully Qualified Name)、字段的名称和描述符(Descriptor)、方法的名称和描述符

  在这里说一下Java中提供阅读字节码文件的工具: javap -verbose className.class;

  访问标志:

    用于识别一些类或者接口层次的访问信息,包括:这个Class是类还是接口;是否定义为public类型;是否定义为abstract类型;如果是类的话,是否被声明为final等

  类索引,父类索引与接口索引集合:

    三项数据来确定这个类的继承关系。类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名。由于Java语言不允许多重继承,所以父类索引只有一个,除了java.lang.Object之外,所有的Java类都有父类,因此除了java.lang.Object外,所有Java类的父类索引都不为0。接口索引集合就用来描述这个类实现了哪些接口,这些被实现的接口将按implements语句(如果这个类本身是一个接口,则应当是extends语句)后的接口顺序从左到右排列在接口索引集合中

  字段表集合:

    描述接口或者类中声明的变量。字段(field)包括类级变量以及实例级变量。

    而字段叫什么名字、字段被定义为什么数据类型,这些都是无法固定的,只能引用常量池中的常量来描述。

    字段表集合中不会列出从超类或者父接口中继承而来的字段,但有可能列出原本Java代码之中不存在的字段,譬如在内部类中为了保持对外部类的访问性,会自动添加指向外部类实例的字段。

  属性表集合:

    存储Class文件、字段表、方法表都自己的属性表集合,以用于描述某些场景专有的信息。如方法的代码就存储在Code属性表中。  

从昨天开始就复工上班了,昨天太累了没有学习今天早上早来一个小时半,把昨天没学的补回来;本来打算把JVM的执行子系统也写成一个大章节,但是后来想想,还是拆分成几个小章节写吧,大章节,自己有时候回顾的时候都看不完,知识量有点多[捂脸]

作者:彼岸舞

时间:2020\03\31

内容关于:JVM

本文部分来源于网络,只做技术分享,一概不负任何责任

JVM学习第三天(JVM的执行子系统)之开篇Class类文件结构的更多相关文章

  1. JVM学习第三天(JVM的执行子系统)之字节码指令

    早上看了Class类文件结构,晚上继续来看字节码指令,毕竟谁也不是一步登天的(说白了还是穷); 字节码指令 Java虚拟机的指令由一个字节长度的.代表着某种特定操作含义的数字(称为操作码,Opcode ...

  2. JVM学习(三)JVM垃圾回收

    一.引用的分类 在了解JVM垃圾回收机制之前,了解一下对象的引用类型是非常必要的. 强引用:GC时不会被回收 软引用:描述有用但不是必须的对象,在发生内存溢出异常之前被回收 弱引用:描述有用但不是必须 ...

  3. JVM学习第三天(JVM的执行子系统)之类加载机制

    好几天没有学习了,前几天因为导出的事情,一直在忙,今天继续学习, 其实今天我也遇到了一个问题,如果有会的兄弟可以评论留给我谢谢; 问题:fastJSON中JSONObject.parseObject做 ...

  4. JVM学习第三天(JVM的执行子系统)之类加载机制补充

    昨晚没看完,今天继续 系统的类加载器 对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间.这句话可以表达得更通俗一些: ...

  5. 重读《深入理解Java虚拟机》三、Java虚拟机执行的数据入口(类文件结构)

    1.Java如何实现平台无关系 Java要实现平台无关系就需要在Java代码和本地机器之间引入一个中间层,实现Java代码和本地机器的解耦,而这个中间层就是字节码.字节码独立于本地机器,以实现代码的可 ...

  6. java之jvm学习笔记三(Class文件检验器)

    java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...

  7. JVM学习笔记之初识JVM(三)

    一.JVM在计算机中的位置 JVM调用操作系统,操作系统调用硬件,硬件反馈信息至操作系统,操作系统反馈信息至JVM 二.JVM的体系结构 JVM在执行过程中对内存的管理分为5个区域: 1.PC寄存器 ...

  8. JVM学习笔记(三):类文件结构

    代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步. 实现语言无关性的基础是虚拟机和字节码存储格式.Java虚拟机不和包括Java在内的任何语言绑定,只与&quo ...

  9. JVM探究 面试题 JVM的位置 三种JVM:HotSpot 新生区 Young/ New 养老区 Old 永久区 Perm 堆内存调优GC的算法有哪些?标记清除法,标记压缩,复制算法,引用计数法

    JVM探究 面试题: 请你弹弹你对JVM的理解?Java8虚拟机和之前的变化更新? 什么是OOM?什么是栈溢出StackOverFlowError?怎么分析 JVM的常用调优参数有哪些? 内存快照如何 ...

随机推荐

  1. 6、单例模式 Singleton模式 只有一个实例 创建型模式

    1.了解Singleton模式 程序在运行时,通常都会生成很多实例.例如,表示字符串的java . lang . string类的实例与字符串是- -对- -的关系,所以当有1000个字符串的时候,会 ...

  2. 1)uboot的编译和烧写

    购买荔枝派ZERO已经将近一个星期了,由于官方资料不够完整一直没有任何进展.经过今夜近三个小时的折腾终于将UBOOT烧写成功,现将过程记录如下: 1)获取官方uboot 源码 : git clone  ...

  3. Docker-Compose介绍,安装和使用

    Docker-Compose 介绍 有时候运行一个镜像需要大量的参数,可以通过Docker-Compose编写这些参数.而且Docker-Compose可以版主我们批量管理容器,这些信息值需要通过一个 ...

  4. MySQL数据的增删改查查查查查查查查查查查查查查查查(查是真的多)

    一 数据的增加 主要是运用insert  into 语句. 格式: insert  into 表名称 values(数据,数据,数据)(要按顺序来,有没有数据的可以加null) 只增加某些字段里数据的 ...

  5. Django-model查询[为空、由某字符串开头、由某字符串结尾、包含某字符串],__isnull、__starswith、__endswith、__contains

    使用属性+__isnull就可以判断此字段为空 a = DatasClass.objects.filter(name__isnull=True) 使用属性+__startswith可以判断属性由某字符 ...

  6. MyBatis使用LocalDateTime遇到的一系列问题

    问题 在Mybaits中传入参数为LocalDateTime,查询发现结果集为空,插入时发现时间相差13小时 测试 新建工程,新建测试库(主要此处新工程使用的JDBC为mysql-connector- ...

  7. ThinkPHP 6.0 基础教程 - 安装

    ThinkPHP6.0 的环境: PHP >= 7.1.0 我本地环境: Win10 PhpStudy 安装 PhpStudy 如果你已经安装 PhpStudy 或其他环境,请忽略这里 安装方法 ...

  8. 实体类转xml

    看项目中需要实体类转xml,大家是拼接的.感觉可以利用反射实现.于是写了下 代码如下 package com.kevin.util; import org.springframework.util.O ...

  9. JAVA8—————StringJoiner类

    JAVA8——StringJoiner类引言:在阅读项目代码是,突然看到了StringJoiner这个类的使用,感觉很有意思,对实际开发中也有用,实际上是运用了StringBuilder的一个拼接字符 ...

  10. 分布式数据库中间件 MyCat | 分库分表实践

    MyCat 简介 MyCat 是一个功能强大的分布式数据库中间件,是一个实现了 MySQL 协议的 Server,前端人员可以把它看做是一个数据库代理中间件,用 MySQL 客户端工具和命令行访问:而 ...