今天继续总结JVM,计划本周完成这个系列的整理、总结。
本节内容枯燥,胆小者勿入!

Write Once,Run Anywhere——byteCode

byteCode 平台无关
java通过存储编译后的字节码,并将字码加载到JVM中,实现了java语言的跨平台。字节码是平台中立的代码存储格式,任意一个平台只要安装了JRE(跟平台有关),那么程序就是可以运行的。

byteCode 语言无关
除此之外,更值得注意的是字节码不仅是平台无关的,也同样是语言无关的,并不是说只有java语言才能生成byteCode,byteCode比java语言有着更强的描述性,而且JVM不与语言进行绑定,所以其他语言(Jython,groovy等),也是可以通过编译为byteCode运行在JVM中的。

Class文件

类文件 {0xCAFEBABE,小版本号,大版本号,常量池大小,常量池数组,访问控制标记,当前类信息,父类信息,实现的接口个数,实现的接口信息数组,域个数,域信息数组,方法个数,方法信息数组,属性个数,属性信息数组
}

一个byteCode文件(.class)一定对应一个java接口或者类,但是一个java接口或者类不一定对应一个.class文件,也有可能只在内存中生成。

一个class文件是一个以Byte为基础单位的二进制流,各项数据、指令紧凑的排列,中间没有任何分隔符、间隙。

javap -verbose 执行后的可视byteCode:

public class com.zs.jvm.byteCode.TestClassminor version: 0major version: 51flags: ACC_PUBLIC, ACC_SUPER
Constant pool:#1 = Class              #2             // com/zs/jvm/byteCode/TestClass#2 = Utf8               com/zs/jvm/byteCode/TestClass#3 = Class              #4             // java/lang/Object#4 = Utf8               java/lang/Object#5 = Utf8               m#6 = Utf8               I#7 = Utf8               <init>#8 = Utf8               ()V#9 = Utf8               Code#10 = Methodref          #3.#11         // java/lang/Object."<init>":()V#11 = NameAndType        #7:#8          // "<init>":()V#12 = Utf8               LineNumberTable#13 = Utf8               LocalVariableTable#14 = Utf8               this#15 = Utf8               Lcom/zs/jvm/byteCode/TestClass;#16 = Utf8               inc#17 = Utf8               ()I#18 = Fieldref           #1.#19         // com/zs/jvm/byteCode/TestClass.m:I#19 = NameAndType        #5:#6          // m:I#20 = Utf8               SourceFile#21 = Utf8               TestClass.java
{public com.zs.jvm.byteCode.TestClass();descriptor: ()Vflags: ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #10                 // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 3: 0LocalVariableTable:Start  Length  Slot  Name   Signature0       5     0  this   Lcom/zs/jvm/byteCode/TestClass;public int inc();descriptor: ()Iflags: ACC_PUBLICCode:stack=2, locals=1, args_size=10: aload_01: getfield      #18                 // Field m:I4: iconst_15: iadd6: ireturnLineNumberTable:line 7: 0LocalVariableTable:Start  Length  Slot  Name   Signature0       7     0  this   Lcom/zs/jvm/byteCode/TestClass;
}

byteCode只存在两种数据类型:无符号数字 与 表。
无符号数字:
基本的数据类型,以u1、u2、u4、u8来分别代表1个字节,2个字节、4个字节,8个字节的无符号数字。无符号数字用来描述数字、索引引用、数据值、UTF-8编码的字符串值。

表:由无符号数字或者表构成的复合数据类型。表通常以”_info”结尾。class文件本质上就是一个表,如下图

从头到尾一项项来看:
magic:
一个4byte的无符号数字,用来确认当前文件是否是class格式文件,是否可以被jvm接收。
minor_version、major_version:
用来判断当前编译的byteCode所属JDK版本号,JDK向下兼容.
constant_pool_count:
用来记录常量池中数据类型的个数。最大值为22(1-22),也就是说常量池总共有21中数据类型。
constant_pool:
常量池 通常存储两种数据:
字面量(litera),如字符串,final常量等
符号引用(Symblic Reference),如类、接口的全限定名称、字段的名称和描述、方法的名称和描述。

access_flag:
用来描述类或接口的访问类型、修饰符等。方法内部也会有这个字段用来描述方法的修饰关键字

this class、super_class、interfaces_count、interfaces
这几个无符号数字,用来描述当前class所属的类型、父类、接口等继承与实现信息

* 字段段表集合 field_info fields*
这个表用于描述接口或类中声明的变量,但不包括方法中的局部变量。
field_info具体结构,如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DEn7ml9m-1661835681889)(http:/F/img.blog.csdn.net/20170406231813514?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGVtb244OQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]

access_flags与之前说过,只是这里的access_flag针对成员变量(类级别的变量),用来描述这个方法是否使用了final、static、volatile等关键字修饰。
name_indexdescriptor_index这两个都是对ConstantPool的引用。

name_index:用来描述成员变量的简单名称,如int indexOf(…)这个方法,name_index在常量池中对应的描述字符串为:“indexOf”

descriptor_index:参数列表、返回值等。

对于数组类型,每一维度将使用一个前置的“[”字符来描述,如一个定义为“java.lang.String[][]”类型的二维数组,
将被记录为:“[[Ljava/lang/String;”,一个整型数组“int[]”将被记录为“[I”。

如:

int indexOf(char[]source,int sourceOffset,int sourceCount,char[]target,int targetOffset,int
targetCount,int fromIndex)

描述为:([CII[CIII)I。
注意顺序:“参数列表 返回类型”

方法表集合 method_info methods
与字段表集合类似,结构如下:

attribute_info后文详细描述。

https://kastor.opaak.org/articles/69-0xcafebabe-java-class-file-format-an-overview.htmlo

属性表集合 attribute_info
class文件本身、方法表(methods_info)、属性表(fields_info)都可以携带属性表(attribute_info),用来描述某些信息。

attribute_info属性表预定义属性如下(不完全):

属性表结构:

待续。。。

深入理解JVM 一字节码详解相关推荐

  1. java 字节码详解_Java基础篇(JVM)——字节码详解

    这是Java基础篇(JVM)的第一篇文章,本来想先说说Java类加载机制的,后来想想,JVM的作用是加载编译器编译好的字节码,并解释成机器码,那么首先应该了解字节码,然后再谈加载字节码的类加载机制似乎 ...

  2. 深入理解JVM一字节码执行

    文章目录 前言 栈帧结构 每个方法调用开始到退出,都对应着一个"栈帧"进站与出站. 运行时栈帧 栈帧-局部变量表 栈帧-操作数栈(Operand Stack) 栈帧-动态连接 栈帧 ...

  3. JVM(1)——字节码

    1.JVM基础 1.1.JDK,JRE,JVM关系 JDK JDK(Java Development Kit) 是用于开发 Java 应用程序的软件开发工具集合,包括 了 Java 运行时的环境(JR ...

  4. JVM之内存结构详解

    对于开发人员来说,如果不了解Java的JVM,那真的是很难写得一手好代码,很难查得一手好bug.同时,JVM也是面试环节的中重灾区.今天开始,<JVM详解>系列开启,带大家深入了解JVM相 ...

  5. java的String类源码详解

    java的String类源码详解 类的定义 public final class Stringimplements java.io.Serializable, Comparable<String ...

  6. JVM之类加载阶段详解

    JVM之类加载阶段详解 类加载阶段总览 加载 获取二进制流 将字节流转换为运行时数据结构 堆中生成Class对象 特殊 连接 验证 准备 解析 名词解释 何时进行 解析哪些类型 初始化 类 接口 使用 ...

  7. JVM运行时区域详解

    转载自 JVM运行时区域详解 我们知道的JVM内存区域有:堆和栈,这是一种泛的分法,也是按运行时区域的一种分法,堆是所有线程共享的一块区域,而栈是线程隔离的,每个线程互不共享. 线程不共享区域 每个线 ...

  8. Go 语言 bytes.Buffer 源码详解之1

    转载地址:Go 语言 bytes.Buffer 源码详解之1 - lifelmy的博客 前言 前面一篇文章 Go语言 strings.Reader 源码详解,我们对 strings 包中的 Reade ...

  9. python接口自动化(七)--状态码详解对照表(详解)

    简介 我们为啥要了解状态码,从它的作用,就不言而喻了.如果不了解,我们就会像个无头苍蝇,横冲直撞.遇到问题也不知道从何处入手,就是想找别人帮忙,也不知道是找前端还是后端的工程师. 状态码的作用是:we ...

最新文章

  1. Google 神秘 Fuchsia OS 的开源线索
  2. Linux高性能网络:协程系列08-协程实现之调度器
  3. listview与gridview点击时的背景色取消
  4. 上帝的玩偶:haXe语言
  5. Ubuntu如何搭建Django与Flup和Nginx环境?
  6. 中快捷搜索_同事用1分钟,我用半小时,原来是因为这8个Word快捷键,秒杀一切办公技巧...
  7. 深入解读 MySQL 底层原理,让性能“飞起来”的方法总结
  8. php怎么使用插件下载,怎么使用下载的jquery插件
  9. 智能环境监测产品浪涌防护整改之TVS管
  10. NPN 、PNP 三极管开关形式的典型接法(注意上下拉电阻)
  11. 5G的遮羞布被撕下了,双十一最畅销的手机竟然是4G手机
  12. c语言 eval,分享:自己写的eval函数
  13. 好性格让孩子受用终生
  14. 交流异步电机的Modelica模型
  15. 前TT(前T/T)与后TT(后T/T),以及信用证(LC,L/C)付款方式比较
  16. linux限制message日志大小,message显示rsyslog日志服务警告信息due to rate-limiting
  17. linux 下 gcc编译程序时,-I(大写i) 与-L(大写l)-l(小写l) 的作用
  18. Scratch之顺序、循环、选择三种程序结构
  19. hdu1814 Peaceful Commission 2-sat
  20. 如何用计算机打出立方,立方米符号怎么打出来

热门文章

  1. wkhtmltopdf 实现html 文档对象转换为pdf 文件核心功能代码
  2. typora编辑器使用教程
  3. OpenCV+MFC学习笔记(二):OpenCV二值化处理图像并在Picture Control中并自适应显示
  4. 《暑期集训总结与心得》
  5. GBA破解老笔记-SD高达G世纪Advance
  6. 安卓微信自动抢红包插件实现和优化
  7. html字体大小怎么设置
  8. 北京1954-3度分带-高斯克吕格投影
  9. C语言实现通讯录详细教学
  10. js读取excel数据后的时间格式转换