在之前的笔记中记录过,Java程序变成可执行文件的步骤是:源代码——>经过编译变成class文件——>经过JVM虚拟机变成可执行的二进制文件。因此,为了对JVM执行程序的过程有一个好的了解,我们需要先明白class文件到底是什么东西,它里面有那些信息以及如何存储的。

Class类文件结构

   Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑排列在Class文件中。当遇到需要占用超过8位字节的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。

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

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

   表是由多个无符号数或者其他表作为数据项构成的复合数据结构,所有表习惯性地以_info结尾。

   我们先来看一下Class文件的格式,然后对这些数据一一进行讲解。

魔数和Class文件的版本

   每个Class文件的头四个字节称为魔数,作用是来表示该文件是一个可以被虚拟机接受的Class文件。其作用类似于扩展名,但扩展名易更改,而魔数来进行类型判别比较安全。

   紧接着的四个字节存储的是Class文件的版本号。第5、6字节为次版本号,第7、8字节为主版本号。

常量池

   版本号之后的就是常量池。常量池是Class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一。

   常量池中主要存放两大类常量,字面量和符号引用。字面量比较接近于Java语言的常量概念,比如文本字符串、被声明为final的常量值等等而符号引用属于编译原理方面的概念,包括了下面三类常量:1、类和接口的全限定名 2、字段的名称和描述符 3、方法的名称和描述符

   Java代码进行编译的时候,没有C那样用"链接"这一步骤,而是在虚拟机加载Class文件的时候进行动态链接。也就是Class文件不会保存各个方法和字段的最终内存布局信息,因此这些字段和方法的符号引用不经过转换的话是无法被虚拟机使用的。当虚拟机运行的时候,需要从常量池获得对应的符号引用,再在类创建或运行的时候解析并翻译到具体内存地址中 ??

   对这些一一列举也没有什么意义,如果需要某一项的内容,可以单独查找。本章我认为更关键的是对Class文件怎么生成的,怎么运作的理解。

   在常量池中,记载了各种常量(包括系统执行时内部需要的)、方法表(用来记录该类的所有方法)、属性表等。他们的运作方法大同小异:通过已经定义的常量(包括字符串常量、方法名之类的信息)来填充对应的表信息,比如方法表中,我们需要得到方法名、返回值、参数等等信息,这些信息都存储在常量池中,只需要引用到对应位置即可表示。而方法表中更为关键的信息就是Code属性了,Code属性表示了该方法的执行过程。

   先看一下Code属性表的内容:



   里面像attribute_name_index之类都是索引,指向常量池中的一个字符串来表示对应的数据常量。关键的地方是code_length和后面的code,他们用来存储Java源代码编译后生成的字节码指令。code_length代码字节码长度,code用于存储字节码指令的一系列字节流,每一个指令都是一个u1类型的单字节。,当虚拟机读到对应字节码的字节后,他会查询出是什么指令并执行。

   

   通过指令的分析,我们可以看到,通过字节码我们可以实现利用常量池中的数据信息,来分析运行结果并执行的。

   在这个字节码中,它执行的数据交换、方法调用都是基于操作栈进行的,比如2A将对象移动到栈顶,B7是以栈顶对象为接受者,他们都是对一个栈进行的操作,但又有像invokespecial这样带参数的指令,这就与单纯使用堆栈进行操作不相符,因此另一个问题是JVM如何堆字节码执行。

类文件结构——深入理解Java虚拟机 笔记三的更多相关文章

  1. 深入理解Java虚拟机第三版,总结笔记【随时更新】

    最近一直在看<深入理解Java虚拟机>第三版,无意中发现了第三版是最近才发行的,听说讲解的JDK版本升级,新增了近50%的内容. 这种神书,看懂了,看进去了,真的看的很快,并没有想象中的晦 ...

  2. Java内存区域与内存溢出异常——深入理解Java虚拟机 笔记一

    Java内存区域 对比与C和C++,Java程序员不需要时时刻刻在意对象的创建和删除过程造成的内存溢出.内存泄露等问题,Java虚拟机很好地帮助我们解决了内存管理的问题,但深入理解Java内存区域,有 ...

  3. 深入理解Java虚拟机笔记

    1. Java虚拟机所管理的内存 2. 对象创建过程 3. GC收集 4. HotSpot算法的实现 5. 垃圾收集器 6. 对象分配内存与回收细节 7. 类文件结构 8. 虚拟机类加载机制 9.类加 ...

  4. 深入理解java虚拟机笔记Chapter12

    (本节笔记的线程收录在线程/并发相关的笔记中,未在此处提及) Java内存模型 Java 内存模型主要由以下三部分构成:1 个主内存.n 个线程.n 个工作内存(与线程一一对应) 主内存与工作内存 J ...

  5. 深入理解java虚拟机笔记Chapter7

    虚拟机类的加载机制 概述 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类的加载机制. 类加载的时机 J ...

  6. 深入理解java虚拟机(三)对象回收判断算法以及死亡过程

    在堆里面存放着Java几乎所有的对象实例,垃圾收集器要进行垃圾回收,要做的第一步便是找出那些对象是需要回收的. 怎么判断对象是否需要回收? 常用的方法有两种. 1.引用计数算法.为每一个对象添加一个引 ...

  7. 深入理解Java虚拟机笔记——虚拟机类加载机制

    目录 概述 动态加载和动态连接 类加载的时机 类的生命周期 被动引用 例子一(调用子类继承父类的字段) 例子二(数组) 例子三(静态常量) 类加载的过程 加载 验证 准备 解析 符号引用 直接引用 初 ...

  8. 深入理解java虚拟机笔记Chapter8

    运行时栈帧结构 栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区中的虚拟机栈(Virtual Machine Stack)的栈元素.栈帧存储了方法 ...

  9. 深入理解java虚拟机笔记之一

    Java的技术体系主要有支撑java程序运行的虚拟机,提供各开发领域接口支持Java API,java编程语言及许多第三方java框架( 如Spring,Structs等)构成. 可以把Java程序设 ...

随机推荐

  1. JDBC 工具类封装

    每次使用jdbc 我们都要 加载驱动类 创建链接 创建Statement 接口对象执行sql 关闭资源 按照这样的套路可以封装一些重用代码方便在其他方法中调用 package com.xzlf.jdb ...

  2. 曹工杂谈--只用一个命令,centos系统里装了啥软件,啥时候装的,全都清清楚楚

    前言 一直以来,对linux的掌握就是半桶水的状态,经常yum装个东西,结果依赖一堆东西:然后再用源码装个东西,只知道make.make install,背后干了啥也不清楚了,卸载也不方便. 这几天工 ...

  3. PHP open_basedir配置未包含upload_tmp_dir 导致服务器不能上传文件

    在做一个上传图片的功能时候发现后台接收到的$_FILES['file']['error'] = 6,这个错误意思是找不到临时文件,或者是临时文件夹无权限,需要更改php.ini文件的 upload_t ...

  4. jstat命令查看JVM 的GC状态

    转载于   https://www.cnblogs.com/alter888/p/10407952.html jstat命令可以查看堆内存各部分的使用量,以及加载类的数量.命令的格式如下: jstat ...

  5. Python 输出 log 到文件的方法

    import loggingfrom logging.handlers import RotatingFileHandler module_name = "test_module" ...

  6. awk命令及随机数的产生

    3.sed 操作,将文件第9行至第15行的数据复制到第十六行 sed -i  '9,15H;16G' 文件 4.用awk获取文件中的三行的倒数第二列字段 awk -F":" 'NR ...

  7. 什么是最好的在线UML软件工具?

    在线UML软件工具允许您创建UML图表,而UML绘图工具可帮助维护您的建模工件并促进不同图表中元素的可重用性.一些UML建模工具还提供复杂的建模功能,例如模型转换,报告,代码工程等. 如果您正在寻找U ...

  8. JAVA_WEB--jsp概述

    JSP全名为Java Server Pages,中文名叫java服务器页面,其根本是一个简化的Servlet设计,它是由Sun Microsystems公司倡导.许多公司参与一起建立的一种动态网页技术 ...

  9. Codeforce-CodeCraft-20 (Div. 2)-C. Primitive Primes(本原多项式+数学推导)

    It is Professor R's last class of his teaching career. Every time Professor R taught a class, he gav ...

  10. 数学--数论-- HDU 2601 An easy problem(约束和)

    Problem Description When Teddy was a child , he was always thinking about some simple math problems ...