Java双亲委派机制

Java 双亲委派机制

首先得了解一下JVM和ClassLoader

JVM

  • 当前主流的有三种JVM:

Sun公司:HotSpot

BEA:JRockit

IBM:J9VM

image-20240301212633477

  • 首先了解一下Java程序从编译到执行的整个生命周期:

.java

(经过javac.exe编译成class文件)=> .class

(经过类加载器ClassLoader,具体过程有加载、链接、初始化)=> 可以由JVM解析的Java字节码文件

(垃圾回收)=> 卸载

​ 在程序执行时,JVM中各区的线程占有情况:

线程私有:程序计数器、虚拟机栈、本地方法区

线程共享:堆、方法区、堆外内存

jvm-framework

  • JVM内存结构
    • 主要结构
      • 方法区
      • 堆区
      • 栈区(java程序栈)
      • 程序计数器:占用某PC寄存器的线程指向了该线程下一条执行语句的地址
      • 本地方法栈
    • 与本地方法接口的连接

​ 由于Java的底层是由C++实现,在Java哲学中,其封装了诸如内存管理、线程管理等底层操作,我们使用navie关键词来

​ 在使用例如线程操作时,线程启动函数start其实是封装了操作系统中的方法 private native void start0();,此部分依靠OS底层实现,即本地方法接口

    public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then
                  it will be passed up the call stack */
            }
        }
    }

    private native void start0();

image-20240301214802452

类加载器

类加载器:对javac生成的class文件进行加载

如图是new一个对象,new的对象的引用存在java栈上,其数据等信息具体存储在堆区中

加载器的分类,我们可以通过一个演示demo进行查看:

  • Bootstrap ClassLoader 启动类加载器
  • Extention ClassLoader 标准扩展类加载器
  • Application ClassLoader 应用类加载器
    public static void main(String[] args) throws Exception {
        Class cls = Car.class;

        ClassLoader classLoader = cls.getClassLoader();
        System.out.println(classLoader);
        System.out.println(classLoader.getParent());
        System.out.println(classLoader.getParent().getParent());

    }

image-20240301223231451

双亲委派机制

当类进行加载时,需要进入到对应的类加载器,否则可能引起安全问题

所以双亲委派机制主要用于解决类错乱加载的问题,总结来说就是优先考虑上层的类加载器:

  • 类加载器收到类加载的请求
  • 将这个请求向上委托给父类加载器去完成,一直向上委托,知道启动类加载
  • 启动加载器检查是否能够加载当前这个类,能加载就结束,使用当前的加载器,否则,抛出异常,适知子加载器进行加载
  • 重复步骤3

img

参考

  1. https://pdai.tech/md/java/jvm/java-jvm-struct.html

  2. https://www.cnblogs.com/gh110/p/14917326.html#3类加载器

posted @ 2024-03-01 22:54  Icfh  阅读(9)  评论(0编辑  收藏  举报