JVM相关问题(补充中...)

Jvm的生命周期:
启动:启动一个java程序时,一个jvm实例就产生了,任何一个拥有main()函数的class都可以作为jvm实例运行的起点

运行:main()作为程序运行的起点,任何其他线程均由该线程启动。main函数是非守护线程。

消亡:当程序中所有的非守护线程终止时

代码的执行过程

类加载器:虚拟机自带的三种类加载器分别为启动类加载器(也叫引导类加载器)bootStrapClassLoader,扩展类加载器(ExtentionClassLoader),应用类加载器(也叫系统类加载器)AppClassLoader

启动类加载器加载java核心类库,用于提供jvm自身需要的类

扩展类加载器加载JDK安装目录下的扩展目录里的类

系统类加载器是程序中默认的类加载器,java应用的类都是由他加载

类加载器的特点

  1. 全盘负责:当一个类加载器加载一个类时,该类所依赖的其他类也会被类加载器加载到内存中
  2. 缓存机制:所有的Class对象都会被缓存,当程序需要用到某个Class对象时,会先去内存中找,找不到才会从.class文件中去读取数据,转化为class对象加载到内存中
  3. 双亲委派机制:如果一个类加载器收到了类加载请求,他并不会先自己去加载,而是把这个请求委托给父类加载器去执行,如果父类加载器还存在父类加载器,则进一步向上委托,依次递归,请求最终达到顶层的启动类加载器。如果父类加载器可以完成类加载任务,就成功返回,如果不能,子加载器才会尝试自己去加载。这么做的好处是能够保证一个类的全局唯一性,并且防止了恶意代码影响核心代码

反向委托:当类加载器加载第三方jar时,比如spi接口(外设接口),这个接口属于核心api,首先通过双亲委派机制将类加载请求委托到引导类加载器,引导类加载器去加载spi核心类,spi接口中使用有第三方的jar包jdbc.jar,第三方的jar需要使用线程上下文类加载器(应用类加载器)去加载,这个步骤就叫反向委托。

沙箱安全机制:沙箱安全机制将java代码限定在jvm的特定运行范围中,并且严格限制代码对本地系统资源进行访问,通过这种方式实现对java代码的有效隔离,防止对本地操作系统造成破坏

类的主动使用和被动使用(主动使用会引起类的初始化)

主动使用的7种情况:
1.创建类的实例

2.访问类或接口的静态变量或者对该静态变量赋值

3.调用类的静态方法

4.反射

5.初始化一个类的子类

6.jvm启动时被标明为启动类的类

7.JDK 7开始提供的动态语言支持:java.lang.invoke. MethodHandle实例的解析结果REF getstatic, REF putstatic, REF invokestatic句柄对应的类没有初始化,则初始化

其他情况均为被动引用

类的加载过程

加载(即通过类加载器加载):类加载器加载.class文件转换成二进制数据存储在jvm的运行时数据区的方法区中,并在堆中生成class对象

验证:对文件格式,元数据,字节码,符号引用做相应的验证,这些验证是分布在不同的环节下进行的,验证的目的就是保证加载的代码不会对jvm产生伤害

准备:对class中的静态变量进行赋值,值类型赋0,引用类型赋null。

ConstantValue属性:当基本类型或String被static final修饰时,javac会在编译期为该常量赋上ConstantValue属性,在类加载的准备阶段,虚拟机便会为拥有该属性的常量设置值

解析:对class的符号引用替换为直接引用

解析分为静态解析和动态解析

静态解析:当class引用的是一个具体的实现类,例如A引用了B,那么当A加载时发现B没有加载,此时就会马上加载B,加载完成后会把B的符号引用替换为B的真实地址

动态解析:当class引用的不是一个具体的实现类,而是抽象类或者接口,那么当程序执行到需要调用引用的类时,才会触发解析

初始化:执行程序中的初始化赋值操作,例如静态变量的赋值,静态代码块等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Superzl1002

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

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

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

打赏作者

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

抵扣说明:

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

余额充值