JVM调优篇之JVM基础入门AND字节码文件解读

目录

    • Java程序编译
    • class文件内容
    • 常量池
    • 附录-访问标识表
    • 附录-常量池类型列表

Java程序编译

Java文件通过编译成class文件后,通过JVM虚拟机解释字节码文件转为操作系统执行的二进制码运行。
在这里插入图片描述
规范

Java虚拟机有自己的一套规范,遵循这套规范,任何形式的语言都可以在JVM上运行,前提是编译成class文件,此规范相见oracle官网文档。

实现
JVM虚拟机落地实现有很多,常见的有:

  • Hotspot,使用最热门的JVM
  • OpenJ9,IBM开发
  • MicroSoft JVM 微软开发
  • TaobaoVM 淘宝开发
  • azul zing VM 垃圾回收行业标杆,最快

class文件内容

从上图内容可看出class文件包以下几个方面内容:

  • 魔数(magic number)占4个字节,固定的值0xcafebabe,主要来校验class文件。
  • version 版本号,分为小版本号minor version和大版本号major version,各占两个字节。
  • 常量池信息(constant_pool),具体的各种常量信息,字符串,类名,方法名,字段名等。
  • 访问标识(access_flag),2个字节描述类与接口的修饰符,有几个常见的常量值见附录-访问标识
  • 当前类(this_class
  • 当前类的父类(super_class
  • 具体的接口信息(interfaces
  • 具体的属性信息(fileds
  • 具体的方法信息(methods
  • 其它附加属性信息(attributes

更具体的内容如下:

项目Value
Magic Number魔数(CAFE BABE)
Minor Number次版本号
Major Number主版本号
constant_pool_count常量池数量
constant_pool常量池具体实现,是一种表
access_flag访问标识
this_class当前类名
super_class父类名称
interfaces_count接口数量
interfaces具体实现的接口信息
fileds_count属性数量
fileds具体属性信息
methods_count方法数量
methods具体方法的信息
attributes_count其它附加属性的数量
attributes其它附加属性具体信息

现在来看具体示例来看上面的代表是什么意思,准备一个简单的类:

public class ByteCode01 {public ByteCode01() {}
}

编译之后的字节码文件:

在这里插入图片描述

class文件中就是一个二进制字节流,非0即1,数据类型有五种,u1,u2,u4,u8和_info表类型

上述这种文件需要借助工具来分析具体内容,在idea安装jclasslib插件看Java文件编译成class文件信息,选中编译后的class文件,如下图所示:

在这里插入图片描述
访问标识是固定的值,通过位运算得出的0x0021既代表public又代表super0x00210x00010x0020位与运算),详见附录-访问标识表

更直观的表现:

在这里插入图片描述

常量池

本类索引即当前类名(this_class),cp_infoconstant_pool的表类型,#2是第二张表,cp_info #2代表常量池第二张表,存的是对cp_info #14的引用,cp_info #14存的是具体的字符串值,就是当前类的类名。

在这里插入图片描述
在这里插入图片描述
class文件中都有属于自己的常量池,常量池包含类型列表,来存储类、方法、字段、接口等信息,以及各种字面量,通过解析常量池可以访问这些字符串信息。比如上图出现的CONSTANT_Utf8_infoCONSTANT_Class_info等详见文末常量池类型列表

着重看下CONSTANT_Utf8_info,它用来存储 UTF-8 编码的字符串,相当于一张常量池表,看一下它的具体结构:

字段名字节数描述
tag1CONSTANT_Utf8_info的常量类型是1(其余的见文末常量池类型列表
length2u2(2 字节无符号数) 类型字段,表示 bytes 部分字节长度,以字节为单位的
byteslength实际字符串数据,采用 UTF-8 编码显示

比如

public class Test {public static void main(String[] args) {System.out.println("Hello, World!");}
}

字符串 Hello, World!,会以 CONSTANT_Utf8_info 类型存储在常量池中,对应的二进制内容或许是:

tag      = 0x01 (标识 CONSTANT_Utf8_info)
length   = 0x000D (字符串的字节长度为 13)
bytes    = 48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 ("Hello, World!" 的 UTF-8 编码)

常量池通常分为下面几种常量值类型:

类型标志(tag)描述
CONSTANT_Utf8_info1UTF-8编码的字符串
CONSTANT_Integer_info3整型字面量
CONSTANT_Float_info4浮点型字面
CONSTANT_Long_info5长整型字面量
CONSTANT_Double_info6双精度浮点型字面量
CONSTANT_Class_info7类或接口的符号引用
CONSTANT_String_info8字符串类型字面量
CONSTANT_Fieldref_info9字段的符号引用
CONSTANT_Methodref_info10类中方法的符号引用
CONSTANT_InterfaceMethodref_info11接口中方法的符号引用
CONSTANT_NameAndType_info12字段或方法的部分符号引用
CONSTANT_MethodHandle_info15表示方法句柄
CONSTANT_MethodType_info16表示方法类型
CONSTANT_InvokeDynamic_info18表示一个动态方法调用点

附录-访问标识表

项目Value
ACC_PUBLIC 0x0001是否是public类型
ACC_FINAL 0x0010是否是NULL
ACC_SUPER 0x0020该标志必须为真
ACC_INTERFACE 0x0200是否为接口
ACC_ABSTRACT 0X0400是否是接口或者抽象类
ACC_SYNTHETIC 0x1000编译器自动生成,非用户代码产生
ACC_ANNOTATION 0x2000是否为注解
ACC_ENUM 0x4000是否为枚举

附录-常量池类型列表

常量类型tag值描述
CONSTANT_Utf8_info1用于存储 UTF-8 编码的字符串
CONSTANT_Integer_info3用于存储 4 字节的整型字面量(int
CONSTANT_Float_info4用于存储 4 字节的浮点型字面量(float
CONSTANT_Long_info5用于存储 8 字节的长整型字面量(long
CONSTANT_Double_info6用于存储 8 字节的双精度浮点型字面量(double
CONSTANT_Class_info7用于存储类或接口的符号引用,引用 CONSTANT_Utf8_info 中的类名
CONSTANT_String_info8用于存储字符串字面量,引用 CONSTANT_Utf8_info 中的字符串内容
CONSTANT_Fieldref_info9用于存储字段的符号引用,引用类和字段的描述信息
CONSTANT_Methodref_info10用于存储类中方法的符号引用,引用类和方法的描述信息
CONSTANT_InterfaceMethodref_info11用于存储接口中方法的符号引用,引用接口和方法的描述信息
CONSTANT_NameAndType_info12用于描述字段或方法的名称和类型,引用名称(Utf8)和描述符(Utf8
CONSTANT_MethodHandle_info15用于存储对方法句柄的引用(invokedynamic 指令用)
CONSTANT_MethodType_info16用于存储方法类型的符号引用,指向方法描述符(Utf8
CONSTANT_Dynamic_info17用于存储动态调用点的信息(JDK 11 引入,支持动态常量)
CONSTANT_InvokeDynamic_info18用于存储动态方法调用点的信息,引用引导方法和动态调用名称
CONSTANT_Module_info19用于存储模块的符号引用(JDK 9 引入)
CONSTANT_Package_info20用于存储包的符号引用(JDK 9 引入)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/887574.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

@sun.misc.Contended

某个类有以下两个属性 volatile int a; volatile int b; int为4字节,两个int为8字节,一个缓存行大小为64字节 故一旦缓存行a失效了,但是b没失效,会连带着b一起失效,因为失效最小的单位就是一个缓存行 这样子会导致效率…

【Petri网导论学习笔记】Petri网导论入门学习(十一) —— 3.3 变迁发生序列与Petri网语言

目录 3.3 变迁发生序列与Petri网语言定义 3.4定义 3.5定义 3.6定理 3.5例 3.9定义 3.7例 3.10定理 3.6定理 3.7 有界Petri网泵引理推论 3.5定义 3.9定理 3.8定义 3.10定义 3.11定义 3.12定理 3.93.3 变迁发生序列与Petri网语言 对于 Petri 网进行分析的另一种方法是考察网系统…

Flink--API 之Transformation-转换算子的使用解析

目录 一、常用转换算子详解 (一)map 算子 (二)flatMap 算子 (三)filter 算子 (四)keyBy 算子 元组类型 POJO (五)reduce 算子 二、合并与连接操作 …

解锁Scala编程:深入文本分析与数据处理的艺术

引言: 在数据科学的世界里,Scala以其强大的并发能力和简洁的语法,成为处理大规模数据集的理想选择。本文将带您踏上一段Scala编程的探索之旅,从基础的文本分析到复杂的数据处理,每一步都精心设计,让您在实…

Top 10 Tools to Level Up Your Prompt Engineering Skills

此文章文字是转载翻译,图片是自已用AI 重新生成的。文字内容来自 https://www.aifire.co/p/top-10-ai-prompt-engineering-tools 供记录学习使用。 Introduction to AI Prompt Engineering AI Prompt Engineering 简介 1,Prompt Engineering 提示工程…

【RK3588 Linux 5.x 内核编程】-内核线程与读写自旋锁

内核线程与读写自旋锁 文章目录 内核线程与读写自旋锁1、读写自旋锁介绍2、Linux内核中的读写自旋锁2.1 初始化2.1.1 静态方法2.1.2 动态方法3、读写自旋锁加锁与解锁3.1 在用户上下文之间锁定3.1.1 读锁3.1.2 写锁3.2 下半部分之间的锁定3.3 在用户上下文和下半部分之间锁定3.…

Rust语言俄罗斯方块(漂亮的界面案例+详细的代码解说+完美运行)

tetris-demo A Tetris example written in Rust using Piston in under 500 lines of code 项目地址: https://gitcode.com/gh_mirrors/te/tetris-demo 项目介绍 "Tetris Example in Rust, v2" 是一个用Rust语言编写的俄罗斯方块游戏示例。这个项目不仅是一个简单…

Spring Boot 与 Spring Cloud Alibaba 版本兼容对照

版本选择要点 Spring Boot 3.x 与 Spring Cloud Alibaba 2022.0.x Spring Boot 3.x 基于 Jakarta EE,javax.* 更换为 jakarta.*。 需要使用 Spring Cloud 2022.0.x 和 Spring Cloud Alibaba 2022.0.x。 Alibaba 2022.0.x 对 Spring Boot 3.x 的支持在其发行说明中…

Oracle, PostgreSQL 字符串排序不一致及调整

有一个使用了不同数据库的应,Oracle 和 PostgreSQL,数据库中的记录完全相同,相同的查询语句(相同的排序,至少从字面上来说是的)取到的记录排序却不同,从而产生了 Bug。 简单演示一下默认排序各自在这两种数据库中的行为…

(免费送源码)计算机毕业设计原创定制:Java+ssm+JSP+Ajax SSM棕榈校园论坛的开发

摘要 随着计算机科学技术的高速发展,计算机成了人们日常生活的必需品,从而也带动了一系列与此相关产业,是人们的生活发生了翻天覆地的变化,而网络化的出现也在改变着人们传统的生活方式,包括工作,学习,社交…

Ubuntu Opencv 源码包安装

说明: ubuntu20.04 建议 使用 opencv-4.6.0版本 ubuntu18.04 建议 使用 opencv-4.5.2-版本 安装包准备 1、下载源码包 OpenCV官网 下载相关版本源码 Sources # 克隆方式 OpenCV 源码git clone https://github.com/opencv/opencv.gitcd opencvgit checkout 4.5.2 …

Linux 下自动化之路:达梦数据库定期备份并推送至 GitLab 全攻略

目录 环境准备 生成SSH 密钥对 数据库备份并推送到gitlab脚本 设置定时任务 环境准备 服务器要有安装达梦数据库(达梦安装这里就不示例了),git 安装Git 1、首先,确保包列表是最新的,运行以下命令: …

极狐GitLab 17.6 正式发布几十项与 DevSecOps 相关的功能【一】

GitLab 是一个全球知名的一体化 DevOps 平台,很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版,专门为中国程序员服务。可以一键式部署极狐GitLab。 学习极狐GitLab 的相关资料: 极狐GitLab 官网极狐…

<项目代码>YOLOv8 停车场空位识别<目标检测>

YOLOv8是一种单阶段(one-stage)检测算法,它将目标检测问题转化为一个回归问题,能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法(如Faster R-CNN),YOLOv8具有更高的…

【智能制造-46】人机工程(工厂自动化)

工作空间设计 设备布局规划 根据人体测量学数据,合理安排自动化设备、生产线和工作区域的布局。例如,考虑工人的操作空间和活动范围,确保他们能够舒适地接近和操作设备。在汽车装配车间,机器人和工人的工作区域应划分明确&#…

Spring Boot 集成 Knife4j 的 Swagger 文档

在开发微服务应用时,API 文档的生成和维护是非常重要的一环。Swagger 是一个非常流行的 API 文档工具,可以帮助我们自动生成 RESTful API 的文档,并提供了一个友好的界面供开发者测试 API。本文将介绍如何在 Spring Boot 项目中集成 Knife4j …

一线大厂面试集锦

String 为什么要设计成不可变的 String被设计成不可变的有以下几个原因: 线程安全:由于String是不可变的,多个线程可以同时访问同一个String对象而无需担心数据被修改。这使得String在多线程环境下是线程安全1. 的。 2.缓存Hash值:由于String是不可变的,它的hashcode可以…

JavaScript:遍历一个对象数组,获取每个对象中 mainKeyId 对应的值,并以这个值作为新属性的键名,给该对象添加一个新属性。

假设我们有一个对象数组,每个对象包含一个 mainKeyId 字段,以 mainKeyId 的值作为新的键名,并给它添加一个新的属性。可以通过以下代码实现: 示例代码: const arr [{ mainKeyId: key1, name: Item 1, value: 10 },{…

php CURL请求502

增加 pm.max_children 的值 当前值为 50,如果并发请求较多,可能会耗尽子进程资源,导致 502。增加到 100 或更高(根据服务器内存和负载能力调整)。 2. 调整 request_terminate_timeout 当前为 100 秒,适合…

微信小程序中会议列表页面的前后端实现

题外话:想通过集成腾讯IM来解决即时聊天的问题,如果含语音视频,腾讯组件一年5万起步,贵了!后面我们改为自己实现这个功能,这里只是个总结而已。 图文会诊需求 首先是个图文列表界面 同个界面可以查看具体…