JVM详解


一、JVM

在这里插入图片描述

  1. 源码到类文件
  2. 类文件到JVM
  3. JVM各种折腾(内部结构、执行方式、垃圾回收、本地调用等)

1.1 源码到类文件

1.1.1 源码demo

编译:类名.java —> 类名.class

1.1.2 前期编译

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

1.1.3 类文件(Class文件)
1.1.3.1 16进制

在这里插入图片描述

1.1.3.2 文件结构

一个class文件由一个ClassFile组成

在这里插入图片描述

1.1.3.3 简单分析

参考上文中的16进制文件来分析,每两个数字为一个u1

  • u4:cafe babe,代表的就是magic
  • u2 + u2:0000 + 0034,转化为10进制为52,表示的是JDK8
  • u2:003f,转化为10进制为63,表示常量池中的数量为62(其值为常量池中常量数 + 1

常量池主要存储两方面内容:

字面量(Literal):文本字符串,final修饰等

符号引用(Symbolic References):类和接口的全限定名、字符名称和描述符、方法名称和描述符

JVM相对class文件来说可以理解为是操作系统;class文件相对于JVM来说可以理解为是汇编语言或者机器语言

1.1.3.4 常量池分析

上面说到常量池中常量的数量是62,现在来具体分析这62个常量,也就是cp_info constant_pool[constant_pool_count - 1]的信息,cp_info其实是一个表格的形式,表中的每个条目都具有以下的通用格式:
在这里插入图片描述
tag是该条目的标签,其如下
在这里插入图片描述

我们接着分析前面的16进制数据,已经分析到了003f,现在开始分析其后面的数据

  1. 往下数一个u1,即0a -> 10,代表的是CONSTANT_Methodref,表示这是一个方法引用,其info如下:

在这里插入图片描述

还需要往下数两个u2

  • u2:即00 0a -> 10,代表的是class_index,表示该方法所属的类在常量池中的索引
  • u2:即00 2b -> 43:代表的是name_and_type_index,代表该方法的名称和类型的索引
  1. 再往下数u1,即08 -> 8:表示的是CONSTANT_String,表示字符串类型
    在这里插入图片描述

    往下数一个u2

    • u2:即00 2c -> 44,代表的是string_index
  2. 往下数一个u1,即09 -> 9,表示的是CONSTANT_Fieldref,表示字段类
    在这里插入图片描述
    往下数u2和u2

    • u2,即00 0d -> 13:代表的是class_index
    • u2,即00 2d -> 45:代表的是name_and_type_index

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

所谓类加载就是:

  • 虚拟机把Class文件加载到内存
  • 并对数据进行校验,转换解析和初始化
  • 形成虚拟机可以直接使用的Java类型,即java.lang.Class

在这里插入图片描述

2.2.1 装载(Load)

查找和导入class文件

  1. 通过一个类的全限定名获取定义此类的二进制字节流(需要借助于类加载器)
  2. 将这个字节流代表的静态存储结构转化为方法区的运行时数据结构
  3. 在Java堆中生成一个代表这个类的java.lang.Class对象,作为对方法区中这些数据的访问入口
    在这里插入图片描述
2.2.2 链接(Link)
2.2.2.1 验证(Vertify)

保证被加载类的正确性

  • 文件格式验证
  • 元数据验证
  • 字节码验证
  • 符号引用验证
2.2.2.2 准备(Prepare)

类的静态变量分配内存,并将其初始化为默认值
在这里插入图片描述

2.2.2.3 解析(Resolve)

把类中的符号引用转换为直接引用

符号引用就是一组符号来描述目标,可以说任何字面量

直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄,换句话说就是其内存地址

​ 解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用限定符7类符号引用进行

2.2.3 初始化(Initialize)

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

在这里插入图片描述

2.2.4 类加载器ClassLoader

就是用来装载Class文件的

2.2.4.1 分类
  1. Bootstrap ClassLoader:负责加载 $JAVA_HOME 中的 jre/lib/rt.jar 里的所有class或Xbootclassoath选项指定的jar包
  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
2.2.4.2 图解

在这里插入图片描述

2.2.4.3 加载原则[双亲委派]
  1. 检查某个类是否已经加载

    自底向上,从Custom ClassLoader到BootStrap ClassLoader逐层检查,只要某个Classloader已加

    载,就视为已加载此类,保证此类只所有ClassLoader加载一次

  2. 加载的顺序

    自顶向下,也就是由上层来逐层尝试加载此类

2.2.4.4 破坏双亲委派
  1. tomcat
  2. SPI机制
  3. OSGi
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

单手提煤气罐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值