深入理解JVM - 类文件结构(上)

简介: 深入理解JVM - 类文件结构(上)

前言



JVM的类文件结构基本都会要记忆的内容,我相信你也记不住,当然我也是记不住的,所以这里只会列出大致的类文件结构,我们需要大致了解类文件结构是怎么一回事就行了,具体到那个位存哪个内容,内容确实太多了,感兴趣可以直接去读书中对应的第6章 类文件结构这一个章节的内容。

类文件结构个人认为需要注意的点就是这几点:大致的类文件结构,部分Jdk的特性如何通过改动class文件结构实现,比如泛型,自动拆装箱,动态代理,lambada语法等。


概述:


其实主要内容就是介绍CLASS的文件结构。

  1. 了解JVM的类文件基本结构。
  2. 了解常量池的内容
  3. 了解重点内容属性表集合


下面是思维导图的地址:www.mubucm.com/doc/1-ZGc-0…


网络异常,图片无法展示
|


什么是Class类文件?


.class文件是由.java通过Javac的命令编译而来的,也是JVM实现跨平台的关键,同时Class类文件实际上的内容是包含字节码指令的二进制文件,而字节码指令简单理解是jvm对于汇编指令的进一步封装,甚至有一些书籍拿字节码的指令来讲部分操作系统的底层逻辑实现,注意不要被洗脑了,JVM的字节码指令只能被JVM识别,放到别的平台就是一堆乱码,如果带歪了建议看CSAPP这本书洗回来。

既然是由外部的.java文件翻译并且加载到虚拟机上,那么class文件的结构毫无疑问需要严格的规定,防止代码破坏jvm正常执行,事实上《JVM虚拟机规范》规定了Class文件的整个结构,对于每一位都有严格的要求,现代的JDK虽然对于这个规范有了不少的改动,但是整体来看最基础的结构还是按照最初始发布的那一套执行,所以基本不需要担心过时的问题。

任意一个class文件对应一个类或者接口定义,class文件结构也可以看做是一种规范,只要其他语言也能遵守class文件的规范,意味着完全可以通过编写其他语言的程序转化为class文件最终翻译到JVM中。


class文件结构


Class文件是一组以8个字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数 据,没有空隙存在。当遇到需要占用8个字节以上空间的数据项时,则会按照高位在前 [2] 的方式分割 成若干个8个字节进行存储。

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

无符号数:代表了基本的数据类型,比如u1、u2、u3等,数字代表了字节,比如1个字节,2个字节,3个字节,无符号数可以描述数字,索引引用或者经过UTF-8的编码为字符串存储

比如\u304这种字符串

:表是由多个无符号数或者其他表作为数据项构成的复合数据类型,习惯性以“_info”结尾。

最后可以整个class文件结构看出如下的一张表。


网络异常,图片无法展示
|


class文件结构详解


了解了class文件的大致结构,下面来聊聊class文件的具体组成了。


魔数0xCAFEBABE


在class文件的结构中,每个Class文件的头4个字节被称为魔数(Magic Number),它唯一的作用是标记这个文件是一个class文件,除此之外没有其他作用,至于为什么叫做咖啡宝贝是因为它象征着著名咖啡品牌Peet’s Coffee并且深受欢迎的Baristas咖啡。


次主版本号


为什么叫做次主版本号?是因为接着魔数的后面的位数第5、6个字节被称为次版本号,第7、8个字节是主版本号。Java的版本号是从45开始的,JDK 1.1之后的每个JDK大版本发布主版本号向上加1(JDK 1.0~1.1使用了45.0~45.3的版本号)。高版本支持向下兼容,但是低版本不支持向上兼容,哪怕代码一模一样。《Java虚拟机规范》

例如,JDK 1.1能支持版本号为45.0~45.65535的Class文件,无法执行版本号为46.0以上的Class文件,而JDK 1.2则能支持45.0~46.65535的Class文件。目前最新的JDK版本为13,可生成的Class文件主版本号最大值为57.0。

下面是书中给出的具体案例:


网络异常,图片无法展示
|


下面是一个JDK版本号对应参考图:


网络异常,图片无法展示
|


从JDK 9开始,Javac编译器不再支持使用-source参数编译版本号小于1.5的源码

原因:JDK9的模块化,以及扩展类加载器的改动。


相关文章
|
2月前
|
安全 Java 应用服务中间件
JVM常见面试题(三):类加载器,双亲委派模型,类装载的执行过程
什么是类加载器,类加载器有哪些;什么是双亲委派模型,JVM为什么采用双亲委派机制,打破双亲委派机制;类装载的执行过程
JVM常见面试题(三):类加载器,双亲委派模型,类装载的执行过程
|
29天前
|
存储 算法 Java
聊聊jvm的内存结构, 以及各种结构的作用
【10月更文挑战第27天】JVM(Java虚拟机)的内存结构主要包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区和运行时常量池。各部分协同工作,为Java程序提供高效稳定的内存管理和运行环境,确保程序的正常执行、数据存储和资源利用。
48 10
|
1月前
|
SQL 缓存 Java
JVM知识体系学习三:class文件初始化过程、硬件层数据一致性(硬件层)、缓存行、指令乱序执行问题、如何保证不乱序(volatile等)
这篇文章详细介绍了JVM中类文件的初始化过程、硬件层面的数据一致性问题、缓存行和伪共享、指令乱序执行问题,以及如何通过`volatile`关键字和`synchronized`关键字来保证数据的有序性和可见性。
30 3
|
1月前
|
缓存 前端开发 Java
JVM知识体系学习二:ClassLoader 类加载器、类加载器层次、类过载过程之双亲委派机制、类加载范围、自定义类加载器、编译器、懒加载模式、打破双亲委派机制
这篇文章详细介绍了JVM中ClassLoader的工作原理,包括类加载器的层次结构、双亲委派机制、类加载过程、自定义类加载器的实现,以及如何打破双亲委派机制来实现热部署等功能。
46 3
|
1月前
|
小程序 Oracle Java
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
这篇文章是关于JVM基础知识的介绍,包括JVM的跨平台和跨语言特性、Class文件格式的详细解析,以及如何使用javap和jclasslib工具来分析Class文件。
45 0
JVM知识体系学习一:JVM了解基础、java编译后class文件的类结构详解,class分析工具 javap 和 jclasslib 的使用
|
3月前
|
存储 算法 Java
JVM组成结构详解:类加载、运行时数据区、执行引擎与垃圾收集器的协同工作
【8月更文挑战第25天】Java虚拟机(JVM)是Java平台的核心,它使Java程序能在任何支持JVM的平台上运行。JVM包含复杂的结构,如类加载子系统、运行时数据区、执行引擎、本地库接口和垃圾收集器。例如,当运行含有第三方库的程序时,类加载子系统会加载必要的.class文件;运行时数据区管理程序数据,如对象实例存储在堆中;执行引擎执行字节码;本地库接口允许Java调用本地应用程序;垃圾收集器则负责清理不再使用的对象,防止内存泄漏。这些组件协同工作,确保了Java程序的高效运行。
27 3
|
3月前
|
C# UED 开发者
WPF动画大揭秘:掌握动画技巧,让你的界面动起来,告别枯燥与乏味!
【8月更文挑战第31天】在WPF应用开发中,动画能显著提升用户体验,使其更加生动有趣。本文将介绍WPF动画的基础知识和实现方法,包括平移、缩放、旋转等常见类型,并通过示例代码展示如何使用`DoubleAnimation`创建平移动画。此外,还将介绍动画触发器的使用,帮助开发者更好地控制动画效果,提升应用的吸引力。
189 0
|
3月前
|
存储 监控 算法
深入解析JVM内部结构及GC机制的实战应用
深入解析JVM内部结构及GC机制的实战应用
|
1月前
|
存储 安全 Java
jvm 锁的 膨胀过程?锁内存怎么变化的
【10月更文挑战第3天】在Java虚拟机(JVM)中,`synchronized`关键字用于实现同步,确保多个线程在访问共享资源时的一致性和线程安全。JVM对`synchronized`进行了优化,以适应不同的竞争场景,这种优化主要体现在锁的膨胀过程,即从偏向锁到轻量级锁,再到重量级锁的转变。下面我们将详细介绍这一过程以及锁在内存中的变化。
37 4
|
12天前
|
Arthas 监控 Java
JVM进阶调优系列(9)大厂面试官:内存溢出几种?能否现场演示一下?| 面试就那点事
本文介绍了JVM内存溢出(OOM)的四种类型:堆内存、栈内存、元数据区和直接内存溢出。每种类型通过示例代码演示了如何触发OOM,并分析了其原因。文章还提供了如何使用JVM命令工具(如jmap、jhat、GCeasy、Arthas等)分析和定位内存溢出问题的方法。最后,强调了合理设置JVM参数和及时回收内存的重要性。