2.认识JVM-类加载机制

目录

1.认识JVM之Classfile:https://www.cnblogs.com/nuti/p/16270652.html

2.认识JVM之类加载机制:https://www.cnblogs.com/nuti/p/16270672.html

3.认识JVM之运行时数据区: https://www.cnblogs.com/nuti/p/16270703.html

4.认识JVM之编译器: https://www.cnblogs.com/nuti/p/16270741.html

5.认识JVM之垃圾收集器: https://www.cnblogs.com/nuti/p/16270755.html

6.认识JVM之JVM内存模型: https://www.cnblogs.com/nuti/p/16270816.html

 

上文地址:https://www.cnblogs.com/nuti/p/16270652.html,接着往下说

 

 

 这次到了ClassLoaderSubsystem

0.介绍引入

  1. 装载:
官网原文
 Loading is the process of finding the binary representation of a class or interface type with a particular name and creating a class or interface from that binary representation
装载是查找具有特定名称的类或接口类型的二进制表示,并根据该二进制表示创建类或接口的过程。说人话就是把它加载到内存中
  1. 链接:
官网原文
 Linking is the process of taking a class or interface and combining it into the run-time state of the Java Virtual Machine so that it can be executed
获取到的类或接口并将其组合到Java虚拟机的运行时状态以便执行的过程,说人话就是把java中的二进制的具体数据映射到内存空间的具体地址 这样cpu才能找到并且执行
  1. 初始化:
官网原文
Initialization of a class or interface consists of executing the class or interface initialization method 

1.Loading

1.1.几种类加载器

类加载无非就是找到class的全路径然后把它装载到内存中,java又是一门面向对象开发的语言,他这个过程肯定用到了 classLoader,这个过程中也会有很多class需要加载
0
一共有4种类加载器
  • rt下面的交给bootstrap类加载器
  • 扩展的交给Extension类加载器
  • classptah下的指定的包交给App类加载器
  • 自定义的则交给custom类加载器
假设一种前提?我自己在业务代码中写了一个classpath写了一个java.lang.string 如果这样的话 岂不是app中和bootstrap中都要加载一番?
其实不会 那么就引入下面的双亲委派机制

2.1.双亲委派机制

检查类是否加载?
检查某个类是否加载 他会从下到上 custom classLoader到BootstrapClassLoader开始逐层检查,只要是某个classLoader加载过了就被看作已经加载过这个类,保证此类只会加载一次
那么由此可见加载器的调用顺序 就是自上而下,由上层来逐层尝试加载此类
打开ClassLoader源码找到loadClass方法,
看到源码中判断父类是否为空 不为空去父类上去看
protected Class<?> loadClass(String name, boolean resolve)
    throws ClassNotFoundException
{
    synchronized (getClassLoadingLock(name)) {
        // First, check if the class has already been loaded
        Class<?> c = findLoadedClass(name);
        if (c == null) {
            long t0 = System.nanoTime();
            try {
                if (parent != null) {
                    c = parent.loadClass(name, false);
                } else {
                    c = findBootstrapClassOrNull(name);
                }
//-----下面省略   

  测试一下

0
那么这样问题又来了,这样一步步去寻找肯定会很消耗性能,那么确定只有一种情况下不需要别的加载器再来参与的前提下,直接指定类加载器呢?

2.2.打破双亲委派

打破双亲委派方式
  1. 复写loadClass
  2. spi机制
  3. Osgi
  4. ...
0

2.Lingking

0

打开官网的lingking就可以发现还有3个小步骤

  1. Verification:验证类的正确性
  2. Preparation:准备为类或者接口的静态字段赋值为默认值
Preparation involves creating the static fields for a class or interface and initializing such fields to their default values
例子:private static int a = 10;这个时候 准备阶段只是会给你附上一个默认值为0
  1. Resolution:解析 动态的将运行时常量池中的符号引用转换为直接引用
Resolution is the process of dynamically determining concrete values from symbolic references in the run-time constant pool
 

3.initializing

Initialization of a class or interface consists of executing its class or interface initialization method
还是上面的那个例子,上面给了一个默认值为0 这里就真正的吧10给了a  private static int a = 10

 

posted @ 2022-05-14 17:01  Nuti  阅读(30)  评论(0编辑  收藏  举报