JVM第二天学习

Method属性

method属性包含三个字段值
名称access_flag 类型 u2 数量1 attributes_count 1
name_index 类型 u2 数量1 attributes_ info attributes------对应attributes_count
名称descriptior_index u2用来描述参数列表(参数类型)返回值void m()等同于()v,String tostring()—>()Ljava/lang/string,在这里插入图片描述

方法的访问标志

方法中的access_flag
在这里插入图片描述

2.2.10 attributes_count 和attribute

附加属性 方法中的附加属性就是code,是具体代码的实现,在写入方法时,能将方法中代码转化成一条条指令
在这里插入图片描述
在官方文档中,我们可以看到很多十六进制的数字,对应方法中code的内容实现
attribute附加属性
附加属性中,有的代码存在内容,有的不存在
1.既有既定属性,也可以自定义
2.code表示的是方法表,方法表能编译成字节码指令,还存放了操作数栈和 局部变量信息。
在这里插入图片描述
u2 attributes_name_index 指向常量池中的CONSTANT_UTF8_info存放的当前属性名字就是code
u4 attribute_length表示code
长度(不包括前6个字节)
u2 max_stack指定当前方法被执行引擎执行时,在栈帧中需要分配的操作栈大小
u2 max_locals指定当前方法被执行引擎执行时,在栈帧中需要分配的局部变量表大小
u4 code_length 指定方法字节码长度,class文件中每条字节码占一个字节
U1 code存放字节码本身指令,长度是 code_length 个字节
u2 exception_table_length指定异常表大小
Exception_table异常表,作用对try-catch-finally的描述,可以看作一个数组,每一个数组项都是一个exception_info结构,一般来说每一个catch块都对应一个exception_info,编译器也会对当前方法生成一些exception_info
在这里插入图片描述
start_pc从字节码code属性中的一部分 起始处到当前异常处理器的起始处的偏移量
end_pc从字节码到起始处到当前异常处理器末尾的偏移量
handler_pc从当前异常处理器用于处理异常(catch块)的第一条指令相对于字节码开始处的偏移量
catch_type是常量池的索引指向的是常量池CONSTANT-class_info数据项,描述了catch块中的异常类型的信息,这个类必须是java.lang.Throwable或者是它的字类
总结:如果偏移量从start_pc到end_pc之间,出现了catch_type所描述 的异常,那么跳转偏移量到handler_pc中去执行,如果catch_type为0代表不引用任何常量池的信息,这个exception_info用于实现finall的子句

类加载和初始化

重点1.双亲委派2.为什么要双亲委派3.描述一下类加载器的层次

class文件 如何加载到内存中的 并且如何执行的
在这里插入图片描述

3.1class Cycle

class 文件在我们硬盘中,三大步骤
1.Loading步骤
将本地的classfile的二进制内容加载到内存中
2.linking步骤
Verification 校验,如果加载的文件字节码头不是CAFEBABE该过程会被拒绝
Preparation 主要作用是将静态变量赋予默认值,假设public static int i =8并不是把i值赋值成8,而是要对静态变量I进行默认值的赋值也就是0.
Resolution 这个class文件中常量池用到的符号转化为内存地址
3.Initializing 静态变量在该步骤下进行复制为初始值,才会调用静态代码块

3.2 ClassLoader

JVM本身 有个类加载器的层次,这个类加载器就是普通的class,这个加载器的层次就是用来加载不同的class
在这里插入图片描述
注意任何一个classfile被加载 到内存中都会存在两个不问
第一部分 二进制classfile缺失被load内存中
第二部分 生成class类对象,class中还会存在其他对象,引用到class对象,而class对象指向classfile的 内存加载
扩展:class对象存储在哪里?-----------metaspace
Metaspace是jdk1.8版本出现的,Metaspace就是方法区methodarea1.8版本移除了永久代,原本1.8版本之前的permgenerationspace部分变成了Metaspace两个地方指代的都是方法区

在这里插入图片描述

最顶层
BootstrapClassLoader主要负责加载jdk中最核心的jar
会出先null值,调用的是最顶层加载器因为是c++实现,在java的类中没有这样的对象区应对他
第二层
Extclassloader加载扩展jar包
第三层
AppClassLoader
加载classpath指定的内容
第四层
自定义加载器
加载自定义类的内容

类加载器的加载过程叫双亲委派,在双亲委派中存在一个概念叫父加载器,(父加载器不是继承关系)父的原因---->因为源码中Classloader抽象类中有一个变量叫Parent
在这里插入图片描述
该图描述的是语法上的继承关系,和父加载器没关系

3.3双亲委派

在这里插入图片描述

class文件通过自定义的classloader加载,如果没有加载,那么委托他的父加载器appclassloader,有则加载没有继续向上,如果顶层加载器也没有加载就会向下委托,当所有下级都无法加载则抛出异常classNotFound
双亲:值从子到父又从父到子
委派:自己不想做的事,委托别人完成
向上委派的时候,父加载器都是到Cache中去寻找,可以把这个缓存理解成list或者数组

为什么要使用双亲委派?

1.防止加载同一个class文件,保证数据的安全
2.保证核心class文件不被篡改,即使被篡改了也不会加载,即使被加载也不会是同一个class对象,为了保证class的执行安全
这部分代码是被写死的。

3.4父加载器

父加载器不是类的加载器,也不是加载器的父类的加载器

在这里插入图片描述

3.5 类加载器的范围

在这里插入图片描述
从上个案例的执行结果中我们可以看出appclassloader和extclassloader都是Launcher的内部类。Launcher是classloader的包装类启动类
在源码中加载路径
Botstrapclassloader
在这里插入图片描述
appclassloader
在这里插入图片描述
extclassloader
在这里插入图片描述

3.6自定义加载器

小demo
在这里插入图片描述
tomcat加载的servlet
spring框架中ApplicationContext
写类库或修改底层框架时,想加载哪个类就加载谁

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值