当前位置: 首页 > news >正文

Java虚拟机ART 读书笔记 第2章 深入理解Class文件格式

GitHub - Omooo/Android-Notes: ✨✨✨这有一包小鱼干,确定不要吃嘛?( 逃

深入理解Android:Java虚拟机ART 读书笔记 以下内容均来自书中内容 建议看原书哦

第2章 深入理解Class文件格式

2.1 class文件总览

Class文件格式全貌 u4:表示这个域长度为4个字节,内容为无符号整数 u2:表示这个域长度为2个字节,内容为无符号整数

Class文件前8个字节依次是magic(4个字节长,取值必须是0xCAFEBABE)、minor_version(2个字节长,表示该class文件版本的小版本信息)和major_verion(2个字节长,表示该class文件版本的大版本信息)。

constant_pool_count表示常量池数组中元素的个数,而constant_pool是一个存储cp_info信息(cp为constant pool缩写,译为常量池)的数组。每一个Class文件都包含一个常量池。常量池在代码中对应为一个数组,其元素的类型就是cp_info。注意,cp数组的索引从1开始。

access_flags:标明该类的访问权限,比如public、private之类的信息。

this_class和super_class:存储的是指向常量池数组元素的索引。通过这两个索引和常量池对应元素的内容,我们可以知道本类和父类的类名(只是类名,不包含包名。类名最终用字符串描述)。

interfaces_count和interfaces:这两个成员表示该类实现了多少个接口以及接口类的类名。和this_class一样,这两个成员也只是常量池数组里的索引号。真正的信息需要通过解析常量池的内容才能得到。

fields_count和fields:该类包含了成员变量的数量和它们的信息。成员变量信息由field_info结构体表示。

methods_count和methods:该类包含了成员函数的数量和它们的信息。成员函数信息由method_info结构体表示。

attributes_count和attributes:该类包含的属性信息。

2.2 常量池及相关内容

常量池的英文叫Constant Pool,对应的数据结构伪代码就是一个类型为cp_info的数组。每一个cp_info对象存储了一个常量项。cp_info对应数据结构的伪代码如下所示。

CONSTANT_String和CONSTANT_Utf8的区别

CONSTANT_Utf8:该常量项真正存储了字符串的内容。以后我们将看到此类型常量项对应的数据结构中有一个字节数组,字符串就存储在这个字节数组中。

CONSTANT_String:代表了一个字符串,但是它本身不包含字符串的内容,而仅仅包含一个指向类型为CONSTANT_Utf8常量项的索引。

信息描述规则:

原始数据类型对应的字符串描述为"B""C""D""F""I""J""S""Z",它们分别对应的Java类型为byte、char、double、float、int、long、short、boolean。

引用数据类型的格式为"LClassName;"。此处的ClassName为对应类的全路径名,比如上例中的"Ljava/lang/String;"。全路径名的“.”号由“/”替代,并且最后必须带分号。

数组也是一种引用类型,数组用"[其他类型的描述名"来表示,比如一个int数组的描述为"[I",一个字符串数组的描述为"[Ljava/lang/String;",一个二维int数组的描述为"[[I"

https://github.com/Omooo/Android-Notes/blob/master/blogs/JVM/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3%20Class%20%E6%96%87%E4%BB%B6%E6%A0%BC%E5%BC%8F/%E5%B8%B8%E9%87%8F%E6%B1%A0%E5%8F%8A%E7%9B%B8%E5%85%B3%E5%86%85%E5%AE%B9.md

javap-verbose class文件名 查看Class代码

2.5 属性介绍

attribute_info { u2 attribute_name_index; // 属性名称,指向常量池中Utf8常量项的索引 u4 attribute_length; // 该属性具体内容的长度,即下面info数组的长度 u1 info[attribute_length]; // 属性具体内容 }

和常量池类型不一样的是,属性是由其名称来区别的,即attribute_info中的attribute_name_index,所指向的Utf8字符串。

虚拟机在解析Class文件的时候是需要校验很多内容的,比如abstract的函数或native的函数就不能携带"Code"属性。

Code属性:

attribute_name_index指向内容为"Code"的Utf8_info常量项。attribute_length表示接下来内容的长度。

max_stack:JVM执行一个指令的时候,该指令的操作数存储在一个名叫“操作数栈(operandstack)”的地方,每一个操作数占用一个或两个(long、double类型的操作数)栈项。stack就是一块只能进行先入后出的内存。max_stack用于说明这个函数在执行过程中,需要最深多少栈空间(也就是多少栈项)。max_locals表示该函数包括最多几个局部变量。注意,max_stack和max_locals都和JVM如何执行一个函数有关。根据JVM官方规范,每一个函数执行的时候都会分配一个操作数栈和局部变量数组。所以Code_attribute需要包含这些内容,这样JVM在执行函数前就可以分配相应的空间。

code_length和code:函数对应的指令内容也就是这个函数的源码经过编译器转换后得到的Java指令码存储在code数组中,其长度由code_length表明。

exception_table_length和exception_table:一个函数可以包含多个try/catch语句,一个try/catch语句对应exception_table数组中的一项。

介绍exception_table之前需要先了解pc(program counter)的概念。JVM执行的时候,会维护一个变量来指向当前要执行的指令,这个变量就叫pc。有了pc的概念,exception_table中各成员变量的含义就比较容易理解了。其中:

  • start_pc描述try/cath语句从哪条指令开始。注意,这个table中的各个pc变量的取值必须位于代表整个函数内容的Java字节码code[code_length]数组中。
  • end_pc表示这个try语句到哪条指令结束。注意,只包括try语句,不包括catch。
  • handler_pc表示catch语句的内容从哪条指令开始。
  • catch_type表示catch中截获的Exception或Error的名字,指向Utf8_info常量项。如果catch_type取值为0,则表示它是final{}语句块。

Code_attribute里常见的属性有:

  • LineNumberTable用于调试,比如指明哪条指令。对应于源码哪一行。
  • LocalVariableTable用于调试,调试时可以用于计算本地变量的值。
  • LocalVariableTypeTable,功能和LocalVariableTable类似。
  • StackMapTable为Java 1.6以上才支持的属性。JVM加载Class文件的时候,将利用该属性的内容对函数进行类型校验(Type Checking)。

LineNumberTable属性:

start_pc:指向Code_attribute中code数组某处指令。

line_number:说明start_pc位于源码的哪一行。注意,多个line_number_table元素可以指向同一行代码。因为一行Java代码很可能编译成多条指令。

LineNumberTable的line 7:0表示code数组里第1个指令码(即code[0])来自源码的第7行。

code[0]解析后得到是new指令。

查看左边的源代码可知,第7行确实对应的是一个new操作。

start_pc和length这两个参数决定了一个局部变量在code数组中的有效范围。

name_index:此局部变量的名字,指向Utf8_info常量项。

descriptor_index:此局部变量的类型,也指向Utf8_info常量项,其内容是Field Descriptor字符串描述。

2.6 Java指令码介绍

根据前述知识,我们知道Code_attribute中的code数组存储了一个函数源码经过编译后得到的Java字节码。根据Java虚拟机规范,code数组只能包括下面两种类型的信息:

首先是Java指令码,即指示JVM该做什么动作,比如是进行加操作还是减操作,或者是new一个对象。在JVM规范中,指令码的长度是1个字节。所以JVM规范中定义的Java指令码的个数不会超过255个(255的16进制表示为0xFF)。

紧接指令码之后的是0个或多个操作数。JVM在执行某条Java指令码的时候,往往还需要其他一些参数。参数可以直接存储在code数组里,也可以存储在操作栈(Operand stack)中。由于不同指令码可能需要不同个数的参数,所以指令码后面的内容可以是参数(如果这条指令码需要参数)也可以是下一条指令(如果这条指令码无需参数)。

invokevirtual指令

对invokevirtual来说,该指令后面需要两个字节的参数。大多数指令执行的时候,JVM需要预先准备好操作数栈,里边存储了该指令需要的信息。

复制一份复制栈顶元素。将新复制的值插入操作数栈,但是位置不在栈顶,而是离当前栈顶元素之后的两个位置。

JAVA VM官方规范The Java® Virtual Machine Specification

invokedynamic的简单介绍 http://www.javaworld.com/article/2860079/scripting-jvm-languages/invokedynamic-101.html

todo:自己用JAVA完成一个class文件解析的程序

相关文章:

Java虚拟机ART 读书笔记 第2章 深入理解Class文件格式

GitHub - Omooo/Android-Notes: ✨✨✨这有一包小鱼干,确定不要吃嘛?( 逃 深入理解Android:Java虚拟机ART 读书笔记 以下内容均来自书中内容 建议看原书哦 第2章 深入理解Class文件格式 2.1 class文件总览 Class文件格式全貌 u4&#xff…...

编程基础 - 初识Linux

编程基础 - 初识Linux 返回序言及专栏目录 文章目录 编程基础 - 初识Linux前言一、Linux发展简介二、现代Linux三、Linux系统各发行版小结 前言 为什么要学习Linux呢?我这Windows用得好好的,简单易用傻瓜式、用的人还超多!但是我要告诉你的…...

c yuv422转yuv420p

思路: yuv422 存储格式为 y u y v y u y v y u y v y u y v yuv420p 存储最简单,先存所以的y,再存u,最后v 所以先把422所有的y存在一起,再提奇数行的u ,偶数行舍弃。提…...

计算机网络 - 路由器查表过程模拟 C++(2024)

1.题目描述 参考计算机网络教材 140 页 4.3 节内容,编程模拟路由器查找路由表的过程,用(目的地址 掩码 下一跳) 的 IP 路由表以及目的地址作为输入,为目的地址查找路由表,找出正确的下一跳并输出结果。 1.…...

实现pytorch版的mobileNetV1

mobileNet具体细节,在前面已做了分析记录:轻量化网络-MobileNet系列-CSDN博客 这里是根据网络结构,搭建模型,用于图像分类任务。 1. 网络结构和基本组件 2. 搭建组件 (1)普通的卷积组件:CBL …...

vue多tab页面全部关闭后自动退出登录

业务场景:主项目是用vue写的单页面应用,但是有多开页面的需求,现在需要在用户关闭了所有的浏览器标签页面后,自动退出登录。 思路:因为是不同的tab页面,我只能用localStorage来通信,新打开一个…...

记一个集群环境部署不完整导致的BUG

一 背景 产品有三个环境:开发测试环境、验收环境、生产环境。 开发测试环境,保持最新的更新; 验收环境,阶段待发布内容; 生产环境,部署稳定内容。 产品为BS架构,后端采用微服务&#xf…...

Go zero copy,复制文件

这里使用零拷贝技术复制文件,从内核态操作源文件和目标文件。避免了在用户态开辟缓冲区,然后从内核态复制文件到用户态的问题。 由内核态完成文件复制操作。 调用的是syscall.Sendfile系统调用函数。 //go:build linuxpackage zero_copyimport ("f…...

http协议九种请求方法介绍及常见状态码

http1.0定义了三种: GET: 向服务器获取资源,比如常见的查询请求POST: 向服务器提交数据而发送的请求Head: 和get类似,返回的响应中没有具体的内容,用于获取报头 http1.1定义了六种 PUT:一般是用于更新请求,…...

详解flink exactly-once和两阶段提交

以下是我们常见的三种 flink 处理语义: 最多一次(At-most-Once):用户的数据只会被处理一次,不管成功还是失败,不会重试也不会重发。 至少一次(At-least-Once):系统会保…...

Qt/QML编程学习之心得:QDbus实现service接口调用(28)

D-Bus协议用于进程间通讯的。 QString value = retrieveValue();QDBusPendingCall pcall = interface->asyncCall(QLatin1String("Process"), value);QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);QObject::connect(watcher, SI…...

前端nginx配置指南

前端项目发布后,有些接口需要在服务器配置反向代理,资源配置gzip压缩,配置跨域允许访问等 配置文件模块概览 配置示例 反向代理 反向代理是Nginx的核心功能之一,是指客户端发送请求到代理服务器,代理服务器再将请求…...

接口测试到底怎么做,5分钟时间看完这篇文章彻底搞清楚

01、通用的项目架构 02、什么是接口 接口:服务端程序对外提供的一种统一的访问方式,通常采用HTTP协议,通过不同的url,不同的请求类型(GET、POST),不同的参数,来执行不同的业务逻辑。…...

显示管理磁盘分区 fdisk

显示管理磁盘分区 fdisk fdisk是用于检查一个磁盘上分区信息最通用的命令。 fdisk可以显示分区信息及一些细节信息,比如文件系统类型等。 设备的名称通常是/dev/sda、/dev/sdb 等。 对于以前的设备有可能还存在设备名为 /dev/hd* (IDE)的设备,这个设…...

Hyperledger Fabric 管理链码 peer lifecycle chaincode 指令使用

链上代码(Chaincode)简称链码,包括系统链码和用户链码。系统链码(System Chaincode)指的是 Fabric Peer 中负责系统配置、查询、背书、验证等平台功能的代码逻辑,运行在 Peer 进程内,将在第 14 …...

L1-011 A-B(Java)

题目 本题要求你计算A−B。不过麻烦的是,A和B都是字符串 —— 即从字符串A中把字符串B所包含的字符全删掉,剩下的字符组成的就是字符串A−B。 输入格式: 输入在2行中先后给出字符串A和B。两字符串的长度都不超过10的四次方,并且…...

系列七、Ribbon

一、Ribbon 1.1、概述 Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具,是Netflix发布的一款开源项目,其主要功能是提供客户端的软件负载均衡算法和服务调用,Ribbon客户端组件提供一系列完善的配置项,例如&#xff1a…...

山东名岳轩印刷包装携专业包装袋盛装亮相2024济南生物发酵展

山东名岳轩印刷包装有限公司盛装亮相2024第12届国际生物发酵展,3月5-7日山东国际会展中心与您相约! 展位号:1号馆F17 山东名岳轩印刷包装有限公司是一家拥有南北两个生产厂区,设计、制版、印刷,营销策划为一体的专业…...

BGP公认必遵属性——Next-hop(一)

BGP公认必遵属性共有三个,分别是:Next-hop、Origin、As-path,本期介绍Next-hop 点赞关注,持续更新!!! Next-hop 华为BGP路由下一跳特点: 默认情况下传给EBGP邻居的BGP路由的下一跳…...

增强Wi-Fi信号的10种方法,值得去尝试

Wi-Fi信号丢失,无线盲区。在一个对一些人来说,上网和呼吸一样必要的世界里,这些问题中的每一个都令人抓狂。 如果你觉得你的Wi-Fi变得迟钝,有很多工具可以用来测试你的互联网速度。你还可以尝试一些技巧来解决网络问题。然而,如果你能获得良好接收的唯一方法是站在无线路…...

第十五章 ECMAScript6新增的常用语法

文章目录 一、声明关键字二、箭头函数三、解构赋值四、展开运算符五、对字符的补充六、Symbol七、对象的简写语法八、Set和Map九、for-of 一、声明关键字 ES6新增的声明关键字: let,const:声明变量class:声明类import&#xff0c…...

vulhub中的Apache SSI 远程命令执行漏洞

Apache SSI 远程命令执行漏洞 1.cd到ssi-rce cd /opt/vulhub/httpd/ssi-rce/ 2.执行docker-compose up -d docker-compose up -d 3.查看靶场是否开启成功 dooker ps 拉取成功了 4.访问url 这里已经执行成功了,注意这里需要加入/upload.php 5.写入一句话木马 &…...

MSB20M-ASEMI迷你贴片整流桥MSB20M

编辑:ll MSB20M-ASEMI迷你贴片整流桥MSB20M 型号:MSB20M 品牌:ASEMI 封装:UMSB-4 特性:贴片、整流桥 最大平均正向电流:2A 最大重复峰值反向电压:1000V 恢复时间:&#xff1…...

工程管理系统功能设计与实践:实现高效、透明的工程管理

在现代化的工程项目管理中,一套功能全面、操作便捷的系统至关重要。本文将介绍一个基于Spring Cloud和Spring Boot技术的Java版工程项目管理系统,结合Vue和ElementUI实现前后端分离。该系统涵盖了项目管理、合同管理、预警管理、竣工管理、质量管理等多个…...

【C#】网址不进行UrlEncode编码会存在一些问题

欢迎来到《小5讲堂》,大家好,我是全栈小5。 这是2024年第3篇文章,此篇文章是C#知识点实践序列文章,博主能力有限,理解水平有限,若有不对之处望指正! 目录 前言数据丢失效果请求端代码接口端代码…...

深入Pandas(二):高级数据处理技巧

文章目录 系列文章目录引言时间序列分析可视化示例 高级数据分析技术分组与聚合操作时间序列分析 高级数据操作数据合并与重塑示例:数据合并merge示例:数据合并concat示例:数据重塑 - 透视表 高级索引技巧 结论 系列文章目录 Python数据分析…...

实验8 分析HTTP协议和DNS

实验8 分析HTTP协议和DNS 一、 实验目的及任务 熟悉并掌握wireshark的基本操作,了解网络协议实体间的交互以及报文交换。分析HTTP协议分析DNS协议 二、 实验设备 与因特网连接的计算机网络系统;主机操作系统为Windows;wireshark等软件。 …...

Talk | EMNLP 2023 最佳长论文:以标签为锚-从信息流动的视角分析上下文学习

本期为TechBeat人工智能社区第561期线上Talk。 北京时间1月4日(周四)20:00,北京大学博士生—王乐安的Talk已准时在TechBeat人工智能社区开播! 他与大家分享的主题是: “以标签为锚-从信息流动的视角分析上下文学习”,介绍了他的团队在上下文学…...

2024年中国电子学会青少年编程等级考试安排的通知

各有关单位、全体考生: 中国电子学会青少年等级考试(以下简称等级考试)是中国电子学会为落实《全民科学素质行动规划纲要》,提升青少年电子信息科学素质水平而开展的社会化评价项目。等级考试自2011年启动以来,作为中国电子学会科…...

[足式机器人]Part3 机构运动学与动力学分析与建模 Ch00-2(2) 质量刚体的在坐标系下运动

本文仅供学习使用,总结很多本现有讲述运动学或动力学书籍后的总结,从矢量的角度进行分析,方法比较传统,但更易理解,并且现有的看似抽象方法,两者本质上并无不同。 2024年底本人学位论文发表后方可摘抄 若有…...

外贸电商网站制作/百度指数的需求指数

简介 所谓的客户生命周期指一个客户对企业而言是有类似生命一样的诞生、成长、成熟、衰老、死亡的过程。具体到不同的行业,对此有不同的详细定义,如在电信行业,所谓的客户生命周期,指的就是电信客户从成为电信公司的客户并开始产…...

租机网站开发/谷歌浏览器直接打开

写在前面 在自己准备写一些简单的verilog教程之前,参考了许多资料----asic-world网站的这套verilog教程即是其一。这套教程写得极好,奈何没有中文,在下只好斗胆翻译过来(加了自己的理解)分享给大家。 这是网站原文&…...

如何做点对点视频网站/站优云seo优化

本篇详解了json_encode()给js数组赋值的相关内容。1.巧用json_encode()给js数组赋值很多时候,我们要把PHP处理后的结果付给js来处理。但是,在给js赋值的时候,单个变量的赋值比较简单且容易实现,只要通过模版标签直接把PHP变量输出…...

黄金网站软件app大全/百度下载软件

452.用最少数量的箭引爆气球题目描述题解Code题目描述 在二维空间中有许多球形的气球。对于每个气球,提供的输入是水平方向上,气球直径的开始和结束坐标。由于它是水平的,所以纵坐标并不重要,因此只要知道开始和结束的横坐标就足够…...

阿里巴巴国际网站做网站可以吗/制作公司网站的公司

一、 三种去重方式 1.HashSet 使用java中的HashSet不能重复的特点去重。优点是容易理解。使用方便。 缺点:占用内存大,性能较低。 2.Redis去重 使用Redis的set进行去重。优点是速度快(Redis本身速度就很快),而且去重不…...

重庆网站建设项目/今日头条荆州新闻

本文要分享的消息推送指的是当iOS端APP被关闭或者处于后台时,还能收到消息/信息/指令的能力。 这种在APP处于后台或关闭情况下的消息推送能力,通常在以下场景下非常有用: 1)IM即时通讯聊天应用:聊天消息通知、音视频聊…...