jvm学习笔记1--java代码编译、执行过程及class文件的解读

jvm学习笔记1–java代码编译、执行过程及class文件的解读

1.一个.java到.class的过程–编译

Java代码编译是由Java源码编译器来完成,也就是Java代码到JVM字节码(.class文件)的过程。使用命令:javac hello.java 就会生成hello.class。这里不过多的对此展开,有兴趣的可以自行百度。

在这里插入图片描述

2.类文件(class文件) 解析

相信大家都打开class文件看过(不是说用反编译工具打开的),是一些16进制的字符串,那他们有什么意义呢,下方是一个class文件的部分代码。

cafe babe 0000 0034 0027 0a00 0600 1809
0019 001a 0800 1b0a 001c 001d 0700 1e07
001f 0100 046e 616d 6501 0012 4c6a 6176
612f 6c61 6e67 2f53 7472 696e 673b 0100
0361 6765 0100 0149 0100 0761 6464 7265
......

要看懂上面的代码,它是有一套语法规则的,要不然反编译工具也不会翻译成Java代码,那它的语法规则是什么呢?每一个Class文件对应于一个如下所示的ClassFile结构体。

ClassFile {
    u4             magic; 
    u2             minor_version;
    u2             major_version;
    u2             constant_pool_count;
    cp_info        constant_pool[constant_pool_count-1];
    u2             access_flags;
    u2             this_class;
    u2             super_class;
    u2             interfaces_count;
    u2             interfaces[interfaces_count];
    u2             fields_count;
    field_info     fields[fields_count];
    u2             methods_count;
    method_info    methods[methods_count];
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

ClassFile结构体中,各项的含义描述如下:

  • magic
    魔数,魔数的唯一作用是确定这个文件是否为一个能被虚拟机所接受的Class文件。魔数值固定为0xCAFEBABE,不会改变。
  • minor_version、major_version
    副版本号和主版本号,minor_version和major_version的值分别表示Class文件的副、主版本。它们共同构成了Class文件的格式版本号。譬如某个Class文件的主版本号为M,副版本号为m,那么这个Class文件的格式版本号就确定为M.m。
  • constant_pool_count
    常量池计数器,constant_pool_count的值等于constant_pool表中的成员数加1。constant_pool表的索引值只有在大于0且小于constant_pool_count时才会被认为是有效的(虽然值为0的constant_pool索引是无效的,但其他用到常量池的数据结构可以使用索引0来表示“不引用任何一个常量池项”的意思),对于long和double类型有例外情况。
  • constant_pool[]
    常量池,constant_pool是一种表结构,它包含Class文件结构及其子结构中引用的所有字符串常量、类或接口名、字段名和其它常量。常量池中的每一项都具备相同的格式特征——第一个字节作为类型标记用于识别该项是哪种类型的常量,称为“tag byte”。常量池的索引范围是1至constant_pool_count−1。
  • access_flags
    访问标志,access_flags是一种掩码标志,用于表示某个类或者接口的访问权限及基础属性。
  • super_class
    父类索引,对于类来说,super_class的值必须为0或者是对constant_pool表中项目的一个有效索引值。

还有接口索引、字段表集合、方法表集合、属性表集合等等,这里简单介绍几个,有兴趣的可以去官网看一下。官网地址:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html。

3.类文件到虚拟机(类加载机制)

类加载机制图解
在这里插入图片描述
装载(Load)

查找和导入class文件

(1)通过一个类的全限定名获取定义此类的二进制字节流
(2)将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
(3)在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口

链接(Link)

  1. 验证(Verify)
    保证被加载类的正确性
  2. 准备(Prepare)
    为类的静态变量分配内存,并将其初始化为默认值
  3. 解析(Resolve)
    把类中的符号引用转换为直接引用

初始化(Initialize)
对类的静态变量,静态代码块执行初始化操作

4.类装载器ClassLoader

在装载(Load)阶段,其中第(1)步:通过类的全限定名获取其定义的二进制字节流,需要借助类装载器完成,顾名思义,就是用来装载Class文件的。
分类
1)Bootstrap ClassLoader 负责加载JAVA_HOME中 jre/lib/rt.jar 里所有的class或Xbootclassoath选项指定的jar包。由C++实现,不是ClassLoader子类。
2)Extension ClassLoader 负责加载java平台中扩展功能的一些jar包,包括JAVA_HOME中jre/lib/*.jar 或 -Djava.ext.dirs指定目录下的jar包。
3)App ClassLoader 负责加载classpath中指定的jar包及 Djava.class.path 所指定目录下的类和jar包。
4)Custom ClassLoader 通过java.lang.ClassLoader的子类自定义加载class,属于应用程序根据
自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader。
图解
在这里插入图片描述
加载原则

检查某个类是否已经加载:顺序是自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个Classloader已加载,就视为已加载此类,保证此类只所有ClassLoader加载一次。
加载的顺序:加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类

双亲委派机制 定义:如果一个类加载器在接到加载类的请求时,它首先不会自己尝试去加载这个类,而是把这个请求任务委托给父类加载器去完成,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。
优势:Java类随着加载它的类加载器一起具备了一种带有优先级的层次关系。比如,Java中的Object类,它存放在rt.jar之中,无论哪一个类加载器要加载这个类,最终都是委派给处于模型最顶端的启动类加载器进行加载,因此Object在各种类加载环境中都是同一个类。如果不采用双亲委派模型,那么由各个类加载器自己取加载的话,那么系统中会存在多种不同的Object 类。
破坏:可以继承ClassLoader类,然后重写其中的loadClass方法,其他方式大家可以自己了解 拓展一下。
类加载的三种方式

类加载的三种方式

  1. 通过命令行启动应用时由JVM初始化加载含有main()方法的主类。
  2. 通过Class.forName()方法动态加载,会默认执行初始化块(static{}),但是Class.forName(name,initialize,loader)中的initialze可指定是否要执行初始化块。
  3. 通过ClassLoader.loadClass()方法动态加载,不会执行初始化块。
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值