zoukankan      html  css  js  c++  java
  • 从JDK源码级别剖析JVM类加载机制

    类加载运行的全过程

    当用java命令运行某个main函数时,首先需要类加载器把主类加载到JVM内存中。

    通过Java命令执行代码的大致流程为

     将编译好的字节码class文件通过java命令,在win操作系统就是一个java.exe文件,这个文件底层是c++语言实现的,通过这个文件调用底层jvm.dll文件创建Java虚拟机,这个jvm.dll文件也是c++语言实现的就是一些类库。在创建JVM虚拟机的过程中会通过c++语言创建一个引导类加载器。最终由C++语言调用java代码创建JVM启动器Launcher,该类由引导类加载器创建其他类加载器,最终调用的Launcher类的getLauncher()方法,这个方法创建加载了扩展类加载器,应用程序类加载器。最终调用loadClass()方法实现类的加载,这个方法体现了双亲委派机制。

    java里面有一下几种类加载器:

    引导类加载器:加载jre/lib下核心jar包 如rt.jar charset.jar

    扩展类加载器:加载jre/lib/ext下面的jar包

    应用程序类加载器:加载自己写的java类

    自定义类加载器:负责加载用户自定义路径下的类包

    如果想要摆脱双亲委派机制可以重写loadclass方法

    //ClassLoader的loadClass方法,里面实现了双亲委派机制
    2 protected Class<?> loadClass(String name, boolean resolve)
    3 throws ClassNotFoundException
    4 {
    5 synchronized (getClassLoadingLock(name)) {
    6 // 检查当前类加载器是否已经加载了该类
    7 Class<?> c = findLoadedClass(name);
    8 if (c == null) {
    9 long t0 = System.nanoTime();
    10 try {
    11 if (parent != null) { //如果当前加载器父加载器不为空则委托父加载器加载该类
    12 c = parent.loadClass(name, false);
    13 } else { //如果当前加载器父加载器为空则委托引导类加载器加载该类
    14 c = findBootstrapClassOrNull(name);
    15 }
    16 } catch (ClassNotFoundException e) {
    17 // ClassNotFoundException thrown if class not found
    18 // from the non‐null parent class loader
    19 }
    2021 if (c == null) {
    22 // If still not found, then invoke findClass in order
    23 // to find the class.
    24 long t1 = System.nanoTime();
    25 //都会调用URLClassLoader的findClass方法在加载器的类路径里查找并加载该类
    26 c = findClass(name);
    27
    28 // this is the defining class loader; record the stats
    29 sun.misc.PerfCounter.getParentDelegationTime().addTime(t1 ‐ t0);
    30 sun.misc.PerfCounter.getFindClassTime().addElapsedTimeFrom(t1);
    31 sun.misc.PerfCounter.getFindClasses().increment();
    32 }
    33 }
    34 if (resolve) { //不会执行
    35 resolveClass(c);
    36 }
    37 return c;
    38 }
    39 }

    如果想自己定义类加载器,定义要加载自己的类路径则重新编写findClass()方法;

    为什么jdk设计者要对类加载实现双亲委派机制?

    1.沙箱安全机制 自己写的java.lang.String.class类不会被加载,这样便可以防止核心API库被随意篡改 
    2.避免类的重复加载 父类加载过得类,子类没必要重复加载
  • 相关阅读:
    编写高性能Web应用程序的10个入门技巧
    C#中class与struct的区别[转]
    web架构设计经验分享 (转)
    NUnit入门篇
    sqlserver 重建日志文件
    ExecuteReader如何取得输出参数和返回值
    防止表单重复提交的几种方案
    Web 2.0 versus Virtual Worlds (转)
    ActionScript 3.0 Step By Step系列(七):使用XML和XMLList类处理XML数据 (转)
    PlayButton Component
  • 原文地址:https://www.cnblogs.com/hwhxb-ds/p/13216529.html
Copyright © 2011-2022 走看看