JVM学习笔记4

bilibili-深入理解JVM 虚拟机 学习笔记

JVM学习笔记 1
JVM学习笔记 2
JVM学习笔记 3

P11 _类加载器双亲委托机制详解(11)

  • 根类加载器
  • 拓展类加载器
    • 加载 $JAVA_HOME/jre/lib/ext/*.jar
    • 加载 -Djava.ext.dirs 指定目录下的 jar 包
      • 特别提醒:设置时别忘了加上系统默认的目录,
      • -Djava.ext.dirs=./xxx:$JAVA_HOME/jre/lib/ext
    • 父加载器为 根类加载器
  • 系统类加载器
    • 加载 classpath 中指定的 jar 包及目录中的 class
    • 加载 -Djava.class.path 指定的目录下 jar 包
  • 用户自定义加载器
    • 用户指定目录
package new_package.jvm.p11;

import jdk.internal.dynalink.ChainedCallSite;
import sun.misc.Launcher;

public class ClassLoaderTest {

    public static void main(String[] args) {
        /**
         * Returns the class loader for the class.  Some implementations may use
         * null to represent the bootstrap class loader. This method will return
         * null in such implementations if this class was loaded by the bootstrap
         * class loader.
         */
        ClassLoader classLoader = String.class.getClassLoader();
        System.out.println(classLoader);
        // null

        ClassLoader classLoader2 = ChainedCallSite.class.getClassLoader();
        System.out.println(classLoader2.getClass().getName());
        // sun.misc.Launcher$ExtClassLoader

        System.out.println(classLoader2.getParent());
        // null

        ClassLoader classLoader3 = Launcher.getLauncher().getClassLoader();
        System.out.println(classLoader3.getClass().getName());
        // sun.misc.Launcher$AppClassLoader

        ClassLoader classLoader4 = ClassLoaderTest.class.getClassLoader();
        System.out.println(classLoader4.getClass().getName());
        // sun.misc.Launcher$AppClassLoader
    }
}

P12 _类加载器与类初始化深度剖析(12)

-XX:+TraceClassLoading 加载类列表

package new_package.jvm.p12;

public class MyTest {
    public static void main(String[] args) {
        System.out.println(Chird.a);
        Chird.dosomething();
    }
}

class Parent {

    static int a = 3;

    static {
        System.out.println("Parent static block");
    }

    static void dosomething(){
        System.out.println("Parent dosomething");
    }
}

class Chird extends Parent {

    static {
        System.out.println("Chird static block");
    }
}
// Parent static block
// 3
// Parent dosomething

// 没有对 Chird 类主动使用
package new_package.jvm.p12;

public class MyTest2 {

    public static void main(String[] args) throws ClassNotFoundException {
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        Class clazz = classLoader.loadClass("new_package.jvm.p12.Parent2");
        System.out.println(clazz);

        System.out.println("---");
        Class clazz2 = Class.forName("new_package.jvm.p12.Parent2");
        System.out.println(clazz2);

    }
}

class Parent2 {
    static {
        System.out.println("Parent2 block");
    }
}

// class new_package.jvm.p12.Parent2
// ---
// Parent2 block
// class new_package.jvm.p12.Parent2

loadClass() 不是对类的主动使用,不会导致类的初始化;

P13_不同的类加载器作用与加载动作分析(13)

多看看 java.lang.ClassLoader 的 javadoc 文档

    /**
     * Returns the system class loader for delegation.  This is the default
     * delegation parent for new <tt>ClassLoader</tt> instances, and is
     * typically the class loader used to start the application.
     *
     * <p> This method is first invoked early in the runtime's startup
     * sequence, at which point it creates the system class loader and sets it
     * as the context class loader of the invoking <tt>Thread</tt>.
     *
     * <p> The default system class loader is an implementation-dependent
     * instance of this class.
     *
     * <p> If the system property "<tt>java.system.class.loader</tt>" is defined
     * when this method is first invoked then the value of that property is
     * taken to be the name of a class that will be returned as the system
     * class loader.  The class is loaded using the default system class loader
     * and must define a public constructor that takes a single parameter of
     * type <tt>ClassLoader</tt> which is used as the delegation parent.  An
     * instance is then created using this constructor with the default system
     * class loader as the parameter.  The resulting class loader is defined
     * to be the system class loader.
     *
     * <p> If a security manager is present, and the invoker's class loader is
     * not <tt>null</tt> and the invoker's class loader is not the same as or
     * an ancestor of the system class loader, then this method invokes the
     * security manager's {@link
     * SecurityManager#checkPermission(java.security.Permission)
     * <tt>checkPermission</tt>} method with a {@link
     * RuntimePermission#RuntimePermission(String)
     * <tt>RuntimePermission("getClassLoader")</tt>} permission to verify
     * access to the system class loader.  If not, a
     * <tt>SecurityException</tt> will be thrown.  </p>
     *
     * @return  The system <tt>ClassLoader</tt> for delegation, or
     *          <tt>null</tt> if none
     *
     * @throws  SecurityException
     *          If a security manager exists and its <tt>checkPermission</tt>
     *          method doesn't allow access to the system class loader.
     *
     * @throws  IllegalStateException
     *          If invoked recursively during the construction of the class
     *          loader specified by the "<tt>java.system.class.loader</tt>"
     *          property.
     *
     * @throws  Error
     *          If the system property "<tt>java.system.class.loader</tt>"
     *          is defined but the named class could not be loaded, the
     *          provider class does not define the required constructor, or an
     *          exception is thrown by that constructor when it is invoked. The
     *          underlying cause of the error can be retrieved via the
     *          {@link Throwable#getCause()} method.
     *
     * @revised  1.4
     */
    public static ClassLoader getSystemClassLoader() {
        // ...
    }
package new_package.jvm.p13;

public class ClassLoaderTest {

    public static void main(String[] args) {
        ClassLoader classLoader = ClassLoader.getSystemClassLoader();
        System.out.println(classLoader);

        while (classLoader != null) {
            classLoader = classLoader.getParent();
            System.out.println(classLoader);
        }

        /**
         * Returns the context ClassLoader for this Thread. The context
         * ClassLoader is provided by the creator of the thread for use
         * by code running in this thread when loading classes and resources.
         * If not {@linkplain #setContextClassLoader set}, the default is the
         * ClassLoader context of the parent Thread. The context ClassLoader of the
         * primordial thread is typically set to the class loader used to load the
         * application.
         *
         * <p>If a security manager is present, and the invoker's class loader is not
         * {@code null} and is not the same as or an ancestor of the context class
         * loader, then this method invokes the security manager's {@link
         * SecurityManager#checkPermission(java.security.Permission) checkPermission}
         * method with a {@link RuntimePermission RuntimePermission}{@code
         * ("getClassLoader")} permission to verify that retrieval of the context
         * class loader is permitted.
         *
         * @return  the context ClassLoader for this Thread, or {@code null}
         *          indicating the system class loader (or, failing that, the
         *          bootstrap class loader)
         *
         * @throws  SecurityException
         *          if the current thread cannot get the context ClassLoader
         *
         * @since 1.2
         */
        ClassLoader classLoader2 = Thread.currentThread().getContextClassLoader();
        System.out.println(classLoader2);
    }
}

// sun.misc.Launcher$AppClassLoader@18b4aac2
// sun.misc.Launcher$ExtClassLoader@2b193f2d
// snull
// sun.misc.Launcher$AppClassLoader@18b4aac2s
package new_package.jvm.p13;

import java.sql.DriverManager;

public class ClassLoaderTest2 {

    public static void main(String[] args) {

        // 获取当前类的 ClassLoader
        ClassLoader classLoader = ClassLoaderTest2.class.getClassLoader();
        System.out.println(classLoader);

        // 获取当前线程上下文的 ClassLoader
        ClassLoader classLoader2 = Thread.currentThread().getContextClassLoader();
        System.out.println(classLoader2);

        // 获取系统的 ClassLoader
        ClassLoader classLoader3 = ClassLoader.getSystemClassLoader();
        System.out.println(classLoader3);

        // ClassLoader classLoader4 = DriverManager.getCallerClassLoader();
    }
}

// sun.misc.Launcher$AppClassLoader@18b4aac2
// sun.misc.Launcher$AppClassLoader@18b4aac2
// sun.misc.Launcher$AppClassLoader@18b4aac2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值