jvm认识与探究(一)类加载机制

JDK8虚拟机官方文档:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/index.html

一、源码到类文件

1.创建一个简单的User.java源文件
class User{
	private String name;
	private Integer age;
	private Integer sex;
	
	public void hello(){
		System.out.printf("hello");
	}
}

经过执行命令

javac User.java
2.得到User.class字节码文件,可通过在命令窗口执行javap -c User.class查看字节码文件

在这里插入图片描述

3.直接打开User.class文件会出现乱码,可以使用subline text工具打开class文件,查看编译后的机器码

在这里插入图片描述

4.编译过程

User.java -> 词法分析器 -> tokens流 -> 语法分析器 -> 语法树/抽象语法树 -> 语义分析器 -> 注解抽象语法树 -> 字节码生成器 -> User.class

5.关于类文件

官方说明https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html

User.class文件的机器码

cafe babe 0000 0033 0020 0a00 0400 1309
0014 0015 0800 1007 0016 0a00 1700 1807
0019 0100 046e 616d 6501 0012 4c6a 6176
612f 6c61 6e67 2f53 7472 696e 673b 0100
0361 6765 0100 134c 6a61 7661 2f6c 616e
......

官方提供参照说明

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];
}

magic (魔术)

magic项目提供标识class文件格式的幻数;它具有价值CAFEBABE,前面的u4代表长度(我理解为4个十六进制长度)

minor_version,major_version

minor_version 和major_version项目 的值是此class文件的次要和主要版本。0000 0033对应十进制的51,代表jdk中的一个版本

constant_pool_count

constant_pool_count项的值等于constant_pool表中的条目数加1,0020表示常量池中有对应十进制的32-1个常量结构

constant_pool []

constant_pool是一个结构表,表示在类文件结构及其子结构中引用的各种字符串常量、类和接口名、字段名和其他常量

其他说明请参考上方提供的类文件官方说明

二、类加载机制(类文件到虚拟机)

1.装载(Load)
查找导入class文件

a.通过一个类的全限定名获取定义此类的二进制字节流
b.将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
c.在虚拟机堆中生成一个代表这个类的java.lang.class对象,最为方法区对这些数据的访问入口

2.链接(Link)
a.验证(Verify)

保证加载类的正确性

α.文件格式验证
β.元数据验证
γ.字节码验证
δ.符号引用验证

b.准备(Prepare)

为类的静态变量分配内存,并将其初始化为默认值

c.解析(Resolve)

把类中的符号引用转换为直接引用(内存地址)

3.初始化(Initialize)
对类的静态变量、静态代码块执行初始化操作
总结:

在这里插入图片描述

三、类装载器

在装载(Load)阶段,其中a步骤:通过类的全限定名获取定义的二进制字节流。这一步骤需要借助类装载器完成,即:加载class文件
1.类装载器分类

a.Bootstrap ClassLoader 负责加载$JAVA_HOME中 jre/lib/rt.jar 里所有的class或 Xbootclassoath选项指定的jar包。由C++实现,不是ClassLoader子类

b.Extension ClassLoader 负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中 jre/lib/*.jar 或 -Djava.ext.dirs指定目录下的jar包。

c.App ClassLoader 负责加载classpath中指定的jar包及 Djava.class.path 所指定目录下的类和 jar包。

d.Custom ClassLoader 通过java.lang.ClassLoader的子类自定义加载class,属于应用程序根据 自身需要自定义的ClassLoader,如tomcat、jboss都会根据j2ee规范自行实现ClassLoader。

2.加载顺序

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

b.加载的顺序:加载的顺序是自顶向下,也就是由上层来逐层尝试加载此类。

在这里插入图片描述

3.双亲委派

如果一个类加载器在接到加载类的请求时,它首先不会自己尝试去加载这个类,而是把这个请求任务委托给父类加载器去完成,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值