深入理解Java虚拟机(二)-类加载机制

类加载机制

在谈类加载机制之前,我们先考虑一下类加载机制是什么。通过解析类文件,您已经知道类文件包含很多内容。根据特定的格式。写类后缀不能称为类文件。虚拟机在读取类文件之前必须有一些approve。

什么是类加载机变量泵

类加载机制就是虚拟机把class文件加载到内存,并对数据进行校验,转换解jvm内存析和初始化,形成虚拟机可以直接使approve用的Java类型(jAPPava.lang.Class)

深入理解Java虚拟机(二)-类加载机制

查找和导入“安装”(class):类文件

通过类的完全限定名称approve获取类的二进制字节流。

将此字节流表数据库查询语句示的静态存储结构转换为方法区域的运行时数据结构

在Java堆中创建此类的对象是方法区域中此appetite的部变量英语分数据的访问门户

深入理解Java虚拟机(二)-类加载机制

变量是什么意思源主页(Li源16源码网站88nk):

检查:以确保加jvm性能调优载的类的准确性

在验证阶段,为了确保准确性,将验数据库系统工程师证文件格式、元数据、字节码jvm优化和符号引用

为类的静态变量分配内存,并准备:将其初始化为默认值

Public static int age=10准备阶段完成后,age的值为0

将:解析类的符号引用转换为直接引用

解析步骤是在虚拟机中用直接引用替换常量池中的符号引用的过程。解析操作主要将类或接口、字段、类JVM所指的方法、接口方法、方法类型、方法句柄和调用限定符7类符号引用作为源代码的主行。

初始化(initializa):类中的静态变量,执行静态代码源块初始化操作

使用

(use)

  • 卸载(unload)
  • 类加载器classloader

    了解了类加载机制后,链接,初始化等操作都是JVM中进行的,只需要把cl数据库系统工程师ass文件通过装载加载到虚拟机就jvm是什么可以,那么class文件又是怎么加载进入虚拟机的呢?答案是需要通过类装载器classloader

    类加载器分类

    booAPPtstrap是最上层的类加载器,级别依次下排

    • Bootstrap ClassLoader: 负责加载$JAVA_HOMEJVM中jre/l数据库软件ib/rt.jar、resources.jar、charsjvm垃圾回收机制ets.jar和capproachlass等或jvm是什么意思者Xbootclasspath选项指定的jar包源码精灵永久兑换码。是cj变量类型有哪些vm垃圾回收机制++实现的不是ClassLoader的字类。
    • Extension ClassLapproveoader: 负责加载Java平台中扩展变量名的一些jar包,包括$JAVA_HOME中jre/源码网站lib/ext/目录写的jar和class文件数据库或-Djava.exe.源码dirs指定目录下的jar包
    • App ClassLoader:数据库 负责加载classpath中指定的jar包及-Djava.class.path所指定目录下的类和jar包
    • Custom Clappstore变量是什么意思assLoader: 通过java.lang.ClassLoader的子类自定义加载class,属于应用程序根变量值数据库自身需要定义的ClassLoader,如tomcat,jboss会根据j2ee规范自行实现ClassLoader

    加载原理(双亲委派)

    所谓双亲委派是指:当一个类加载器收到了类加载的请求的时候,他不会直接去加载指jvm是什么定的类,而是把这个源码1688请求委托给自己的父加载器去加载。只有父加载器无法加载这个类的时候,才会由当前这个加载器来负责类的加载。

    当一个类被自下而上的委托给父加载器的时候,最终都会到bootstrap classjvm调优loader但会因为bootstrap不负责加jvm调优载该类,在由下一级的ext classloader来进行加载,如果在不符数据库系统的核心是合就继续往下一级,直到被负责该类appetite的加JVM载器来加载。

    父子加载器是继承关系吗?怎么AppClassLoader没有继承ExtClassLoader?

    在双亲委派中,类加approve载器之间的父子关系没有继承关系来实现,通过内部appstore成员来定义

    public abstract class ClassLoader {
        private final ClassLoader parent;
    }    
    

    接下来通过一jvm调优个小例子来看一下类加载器

    public class TryClassLoader {
        public static void main(String[] args){
            TryJVM jvm = new TryJVM();
            //app classloader
            System.out.println("1" + jvm.getClass().getClassLoader());
            //ext classloader
            System.out.println("2" + jvm.getClass().getClassLoader().getParent());
            //bootstrap classloader
            System.out.println("3" + jvm.getClass().getClassLoader().getParent().getParent());
            //java本身类
            System.out.println("4" + new String().getClass().getClassLoader());
            System.out.println("4" + new Object().getClass().getClassLoader());
        }
    }
    

    输出结果

    1sun.misc.Launcher$AppClassLoader@73d16e93
    2sun.misc.Launcher$ExtClassLoader@15db9742
    3null
    4null
    

    通过例子可以看到我们自己定义的类使用App ClassLoader,也可以看到数据库系统概论Ap源码之家p和Ext各自的父加载器,通过String和Object类也可以看到rtjvm垃圾回收机制.jar下面的类使用jvm是什么意思的是bootstrap加载器,返回nul数据库软件l表示使用bootstrap。

    JDKjvm是什么意思 API对于getClassLoader()的描述

    Returns the class loader for the class. Soapplicationme implementations may use null to represent t变量名的命名规则he boots变量是什么意思trap class数据库系统概论 loader. This method will return null in such implementa数据库管理系统tions if this class was loaded b源码精灵永久兑换码y the bootstrap class loader.

    ClassLoader.j数据库系统概论第五版变量是什么意思课后答案ava源码

    public Class<?> loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
    }
    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);
                    }
                } catch (ClassNotFoundException e) {
                    // ClassNotFoundException thrown if class not found
                    // from the non-null parent class loader
                }
                if (c == null) {
                    // If still not found, then invoke findClass in order
                    // to find the class.
                    long t1 = System.nanoTime();
                    c = findClass(name);
                    // this is the defining class loader; record the stats
                    sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 - t0);
                    sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
                    sun.misc.PerfCounter.getFindClasses().increment();
                }
            }
            if (resolve) {
                resolveClass(c);
            }
            return c;
        }
    }
    

    变量是什么意思过源码可以看到

    • 1.先检查类是否已经被加载过
    • 2.若没有加载则调用父加载器的loadClass()方法进行加载
    • 3.若父加载器为空则默认使用启appoint源码ment动类加载器作为父加载器
    • 4.如果父类加载失败,抛出变量名ClassNotFoundException异常后,再调用自己的findClass()方法进行加载

    在这里也可以发现JVM通变量是什么意思过自上而下加载类到jvm优化JVM中,通过自下而上的方变量之间的关系approve检查类是否已经被加载,如果已经被下数据库设计级的类加载器加载,那么就不需要再次加载

    破坏双亲委派

    根据ClassLoader的loadClass方法可以知道双亲委派的实现,那么为什么要破坏双亲源码1688委派呢jvm原理数据库查询语句

    • 举个例子Tomcat破坏双亲委派

    tomcat作为web容器会部署多个应用,不同应用的依赖可能相同可数据库有哪几种能不同,如果多个应用中依赖同一个依赖的不同版本源码精灵永久兑换码,这些不同版本中很多类的全路径是是一样的,如果是双亲委派是无法加载多个相同的类的。

    tomcat为了实现隔离性为先加源码编辑器下载载每个we数据库有哪源码中的图片几种b应用自己定义的类,每一变量与函数个应用自己的类加载器先加载本身应变量与函数用目录下的class文件,加载不到时候再去To变量英语mcat的jvm调优CommonClassLoader。

    • Jjvm垃圾回收机制DBC,JNDI需要加载SPI接口实现类

    在使用JDBC服务源码1688的时候,approach创建数据库数据库有哪几种接池一般通过Conn数据库系统工程师ection conn = DriverManager.getConapproachnection("jdbc:源码编辑器下载//mysql://host:3306/mysql","root","123456")代码来创建数据库连接,我们都知道Ja变量类型有哪些v源码时代a提供了JDBC的驱动接口appointmentDrive源码精灵永久兑换码r.java各个厂商会自己实现适配自源码交易平台己的Driv数据库管理系统er。

    因此通过查看DriverManager生成conappetiten的源码源码交易平台

    public class DriverManager {
        static {
        loadInitialDrivers();
        println("JDBC DriverManager initialized");
        ```
    private static void loadInitialDrivers() {
        String drivers;
        ......
        // If the driver is packaged as a Service Provider, load it.
        // Get all the drivers through the classloader
        // exposed as a java.sql.Driver.class service.
        // ServiceLoader.load() replaces the sun.misc.Providers()
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            public Void run() {
                ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class);
                Iterator<Driver> driversIterator = loadedDrivers.iterator();
        ......
        }
    }
    

    分析这个代码可以知道DriverManager会被bootstrapapplication类加载APP器加载,因为他在rt.jar中,但是源码编辑器下载当加载器加载到这里的时候,会加载所有Driver的实现类,这些实现类都是第三方按照JDBC的标准来实现的,那么按照源码编程器双亲委派来看,这些第三方的类是不能被bootst源码交易平源码编程器rap加载的,但是这些类也明明被加载了,不然我们怎么用呢?

    查看ServiceLoader源码可以看到,ServiceLo数据库系统的核心是ader中通jvm面试题过引入Thread.cur数据库系统工程师rentThrea数据库有哪几种d().getCont变量的定义extC变量之间的关系lassLoadeappearr();类加载器来加载Dri变量英语ver的实现类,默认情况appleTh变量read.currentThrapproveead().getContextClassLoader(appear)是AppClas数据库设计sLoader这样便破坏了双亲委派原则。

    public static <S> ServiceLoader<S> load(Class<S> service) {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        return ServiceLoader.load(service, cl);
    }
    

    看下官方对于getCon变量之间jvm优化的关系textClassLoader的解释

    Returns the context ClassLoader for变量名的命名规则 t变量jvm是什么名的命名规则his Thread. The context
    ClassLoader is provided by the creator of变量泵 the thread for use
    by code runni变量名ng in this thread whe数据库软件n loa源码编程器ding classes and resources.
    If not {@linkplain #setContextClas数据库系统的核心是sLoader set}, the default is the
    ClasappreciatesLoader context of the pa变量名rent Thread. The context数据库查询语jvm原理 ClassLoader of the primordialjvm是什么 thread is typiappearancec数据库系统工程师ally set to the class loader used to load the application.数据库有哪几种

    数据库管理系统点看最后一句话:原始线程的上下文ClassLoader通常设置为用源码编辑器于加载应数据库用程序的类加载器变量名(App ClassLoadejvm优化r)

    Tappearancehe context Class源码之家Loader of the primordial thread is typically set to the class loader used to lapproveoad theapplication application.

    到这里我们就明白了当JDBC这样变量的定义的使用SP数据库系统概论I机制,通过第三方来提供实现类的,在最开始通过boo变量之间的关系tstrap加载DriverManager源码编程器类,在DriverManager中又使用Thre变量ad.currentThread().getapproveContextjvm性能调优ClassLoader()也就是App ClassLoader来加载第三方提供的类,从而破approach坏了双亲委派机制。