溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

JVM中classloader的作用是什么

發(fā)布時(shí)間:2021-06-23 10:49:44 來(lái)源:億速云 閱讀:153 作者:chen 欄目:大數(shù)據(jù)

這篇文章主要講解了“JVM中classloader的作用是什么”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“JVM中classloader的作用是什么”吧!

方法

  • public Class<?> loadClass(String name) throws ClassNotFoundException 通過(guò)類(lèi)名發(fā)揮這個(gè)類(lèi)的Class實(shí)例

  • protected final Class<?> defineClass(byte[] b,int off,int len) 根據(jù)給定的字節(jié)碼流 b,off 和 len 參數(shù)表示實(shí)際的 class 信息在byte 數(shù)組中的位置和長(zhǎng)度,其中 byte 數(shù)組 b是 classloader 從外部獲取的

  • protected Class<?> findClass(String name)throws ClassNotFoundException 查看一個(gè)類(lèi)

  • protected final Class<?> findLoadedClass(String name)

分類(lèi)

  • BootStrap ClassLoader

  • Extension ClassLoader

  • AppClassLoader JVM中classloader的作用是什么 啟動(dòng)類(lèi)加載器負(fù)責(zé)加載系統(tǒng)的核心類(lèi)(rt.jar的java類(lèi)),擴(kuò)展類(lèi)加載器加載 %JAVA_HOME/lib/ext/*.jar中的類(lèi),應(yīng)用類(lèi)加載器用于加載用戶(hù)類(lèi) (classpath),自定義類(lèi)加載器加載一些特殊路徑的類(lèi)(自定義classloader)

雙親委托

  1. 當(dāng)前 classloader 首先從自己已經(jīng)加載的類(lèi)中查詢(xún)是否此類(lèi)已經(jīng)加載,如果已經(jīng)加載了則直接返回原來(lái)已經(jīng)加載的類(lèi)

  2. 當(dāng)前 classloader 的緩存中沒(méi)有找到被加載的類(lèi)的時(shí)候,委托父類(lèi)加載器去加載,父類(lèi)加載器采用同樣的策略,首先查下自己的緩存,然后委托父類(lèi)去加載,一直到 bootstrap classloader

  3. 當(dāng)所有的父類(lèi)加載器都沒(méi)有加載的時(shí)候,再由當(dāng)前的類(lèi)加載器加載,并將其放入自己的緩存中,下次請(qǐng)求的時(shí)候直接返回

  4. 一直循環(huán)重復(fù)

作用

  • 各個(gè)類(lèi)加載器的基礎(chǔ)類(lèi)統(tǒng)一

JVM中classloader的作用是什么

jar -cvf test.jar HelloLoader.class 把class打包成jar

Extension ClassLoader

例子:在 ext 路徑下放一個(gè)自己 jar 包并加載

package com.mousycoder.server;

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}

idea 通過(guò) structs->artifacts->jar 然后 build-> build artifacts->build 生成 helloworld.jar 放到 /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext

package com.mousycoder.mycode.thinking_in_jvm;

import java.lang.reflect.Method;

/**
 * @version 1.0
 * @author: mousycoder
 * @date: 2019-09-06 10:35
 */
public class ExtClassLoader {

    public static void main(String[] args) throws ClassNotFoundException {
        System.out.println(System.getProperty("java.ext.dirs"));
        Class<?> helloClass = Class.forName("com.mousycoder.server.HelloWorld");
        System.out.println(helloClass.getClassLoader());
    }
}

輸出

/Users/mousycoder/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java
sun.misc.Launcher$ExtClassLoader@610455d6

可以看出是 ExtClassLoader 加載 java.ext.dirs 目錄

自定義類(lèi)加載器

package com.mousycoder.mycode.thinking_in_jvm;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * @version 1.0
 * @author: mousycoder
 * @date: 2019-09-06 11:13
 */
public class MyClassLoader extends ClassLoader {

    private final static Path DEFAULT_CLASS_PATH = Paths.get("","/Users/mousycoder/My");

    private final Path classDir;

    public MyClassLoader(){
        super();
        this.classDir = DEFAULT_CLASS_PATH;

    }

    public MyClassLoader(String classDir){
        super();
        this.classDir = Paths.get(classDir);
    }

    public MyClassLoader(String classDir, ClassLoader parent){
        super(parent);
        this.classDir = Paths.get(classDir);
    }

    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {
        try {
            byte[] classBytes = this.readClassBytes(name);

            if (null == classBytes || 0 == classBytes.length){
                throw new ClassNotFoundException("can not load the class" + name);
            }
            return this.defineClass(name,classBytes,0,classBytes.length);
        } catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }


    private byte[] readClassBytes(String name) throws ClassNotFoundException, IOException {
        String classPath = name.replace(".","/");
        Path classFullPath = classDir.resolve( "HelloWorld1.class");
        if (!classFullPath.toFile().exists()){
            throw new ClassNotFoundException("The class" + name + "mpt found");
        }

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()){
            Files.copy(classFullPath,baos);
            return baos.toByteArray();
        } catch (IOException e){
            throw new ClassNotFoundException("load the class " + name + "occur error",e);
        }

    }


    @Override
    public String toString() {
        return "My ClassLoader";
    }
}

package com.mousycoder.mycode.thinking_in_jvm;

/**
 * @version 1.0
 * @author: mousycoder
 * @date: 2019-09-06 11:34
 */
public class MyClassLoaderTest {

    public static void main(String[] args) throws ClassNotFoundException {
        MyClassLoader classLoader = new MyClassLoader();
        Class<?> class1 = classLoader.loadClass("com.mousycoder.mycode.thinking_in_jvm.HelloWorld1");
        System.out.println(class1.getClassLoader());
    }
}
package com.mousycoder.mycode.thinking_in_jvm;

/**
 * @version 1.0
 * @author: mousycoder
 * @date: 2019-09-06 11:46
 */
public class HelloWorld1 {
    public static void main(String[] args) {
        System.out.println("Hello world1 ");
    }
}

把helloword1變成class放到/Users/mousycoder/My目錄下即可 輸出 My ClassLoader 代表 自定義類(lèi)加載器加載了該類(lèi)

上下文類(lèi)加載器

JVM中classloader的作用是什么

作用

打破雙親委托機(jī)制,讓上層父類(lèi)加載器可以使用子類(lèi)的加載器加載對(duì)象,比如Spi中的接口類(lèi)在系統(tǒng)加載器中,但是實(shí)現(xiàn)類(lèi)在應(yīng)用加載器中

Tomcat 類(lèi)加載器

目的

  1. 保證每個(gè)應(yīng)用的類(lèi)庫(kù)獨(dú)立隔離(即使同限定名不同版本的)

  2. 保證相同類(lèi)庫(kù)相同版本的類(lèi)庫(kù)共享

  3. 保證容器自身的類(lèi)庫(kù)和程序獨(dú)立

加載順序

  1. bootstrap 引導(dǎo)類(lèi)加載器

  2. system 系統(tǒng)類(lèi)加載器

  3. 應(yīng)用類(lèi)加載器 WEB-INF/classes

  4. 應(yīng)用類(lèi)加載器 WEB-INF/lib

  5. common 類(lèi)加載器 CATALINA/lib

感謝各位的閱讀,以上就是“JVM中classloader的作用是什么”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)JVM中classloader的作用是什么這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

jvm
AI