<small id='FAQZo0IaC'></small> <noframes id='ZGiFlqh'>

  • <tfoot id='Dp5MUKfl4x'></tfoot>

      <legend id='rIYf'><style id='Kl0764WdsQ'><dir id='RpyXv'><q id='hQjyd'></q></dir></style></legend>
      <i id='lh957'><tr id='Y6eMKwsR'><dt id='4ab3W'><q id='kxs4mru'><span id='MZkl'><b id='HjiCuMhI'><form id='jJYBWZ'><ins id='sFH6dD59h'></ins><ul id='HOaEwz'></ul><sub id='Sl9ET'></sub></form><legend id='RaUMj'></legend><bdo id='WVOUD057xz'><pre id='WzTLBu0'><center id='ZATX'></center></pre></bdo></b><th id='MYbu'></th></span></q></dt></tr></i><div id='tJmTN0deKP'><tfoot id='gK1qWph9'></tfoot><dl id='kHZU'><fieldset id='X2cHKD1lm7'></fieldset></dl></div>

          <bdo id='6O5I'></bdo><ul id='F4Wxz0qA'></ul>

          1. <li id='EtBqx'></li>
            登陆

            一号站平台app下载-十年架构师干货总结:Java 的类加载机制

            admin 2019-07-11 171人围观 ,发现0个评论

            01、字节码

            在聊 Java 类加载机制之前,需求先了解一下 Java 字节码,由于它和类加载机制休戚相关。

            计算机只知道 0 和 1,所以任何言语编写的程序都需求编译成机器码才干被计算机了解,然后履行,Java 也不破例。

            Java 在诞生的时分喊出了一个十分牛逼的标语:“Write Once, Run Anywhere”,为了达到这个意图,Sun 公司发布了许多可以在不同渠道(Windows、Linux)上运转的 Java 虚拟机(JVM)——担任载入和履行 Java 编译后的字节码。

            究竟 Java 字节码是什么姿态,咱们凭借一段简略的代码来看一看。

            源码如下:

            package com.cmower.java_demo;
            public class Test {
            public static void main(String[] args) {
            System.out.println("缄默沉静王二");
            }
            }

            代码编译通往后,经过 xxd Test.class 指令查看一下这个字节码文件。

            xxd Test.class
            00000000: cafe babe 0000 0034 0022 0700 0201 0019 .......4."......
            00000010: 636f 6d2f 636d 6f77 6572 2f6a 6176 615f com/cmower/java_
            00000020: 6465 6d6f 2f54 6573 7407 0004 0100 106a demo/Test......j
            00000030: 6176 612f 6c61 6e67 2f4f 626a 6563 7401 ava/lang/Object.
            00000040: 0006 3c69 6e69 743e 0100 0328 2956 0100 .....()V..
            00000050: 0443 6f64 650a 0003 0009 0c00 0500 0601 .Code...........
            00000060: 000f 4c69 6e65 4e75 6d62 6572 5461 626c ..LineNumberTabl

            感觉有点懵逼,对不对?

            懵就对了。

            这段字节码中的 cafe babe 被称为“魔数”,是 JVM 辨认 .class 文件的标志。文件格局的定制者可以自由挑选魔数值(只需没用过),比方说 .png 文件的魔数是 8950 4e47 。

            至于其他内容嘛,可以挑选忘记了。

            02、类加载进程

            了解了 Java 字节码后,咱们来聊聊 Java 的类加载进程。

            Java 白芍的功效与作用的类加载进程可以分为 5 个阶段:载入、验证、预备、解析和初始化。这 5 个阶段一般是次序发作的,但在动态绑定的状况下,解析阶段发作在初始化阶段之后。

            1)Loading(载入)

            JVM 在该阶段的首要意图是将字节码从不同的数据源(可能一号站平台app下载-十年架构师干货总结:Java 的类加载机制是 class 文件、也可能是 jar 包,乃至网络)转化为二进制字节省加载到内存中,并生成一个代表该类的 java.lang.Class 方针。

            2)Verification(验证)

            JVM 会在该阶段对二进制字节省进行校验,只需契合 JVM 字节码标准的才干被 JVM 正确履行。该阶段是确保 JVM 安全的重要屏障,一号站平台app下载-十年架构师干货总结:Java 的类加载机制下面是一些首要的查看。

            cafe bene

            3)Preparation(预备)

            JVM 会在该阶段对类变量(也称为静态变量, static 关键字润饰的)分配内存并初始化(对应数据类型的默许初始值,如 0、0L、null、false 等)。

            也便是说,假如有这样一段代码:

            public String chenmo = "缄默沉静";
            public static String wanger = "王二";
            public static final String cmower = "缄默沉静王二";

            chenmo 不会被分配内存,而 wanger 会;但 wanger 的初始值不是“王二”而是 null 。

            需求留意的是, static final 润饰的变量被称作为常量,和类变量不同。常量一旦赋值就不会改变了,所以 cmower 在预备阶段的值为“缄默沉静王二”而不是 null 。

            4)Resolution(解析)

            该阶段将常量池中的符号引证转化为直接引证。

            what?符号引证,直接引证?

            符号引证以一组符号(任何方式的字面量,只需在运用时可以无歧义的定位到方针即可)来描绘所引证的方针。

            在编译时,Java 类并不知道所引证的类的实践地址,因而只能运用符号引证来替代。比方 com.Wanger 类引证了 com.Chenmo 类,编译时 Wanger 类并不知道 Chenmo 类的实践内存地址,因而只能运用符号 com.Chenmo 。

            直接引证经过对符号引证进行解析,找到引证的实践内存地址。

            5)Initialization(初始化)

            该阶段是类加载进程的终究一步。在预备阶段,类变量现已被赋过默许初始值,而在初始化阶段,类变量将被赋值为代码希望赋的值。换句话说,初始化阶段是履行类结构器办法的进程一号站平台app下载-十年架构师干货总结:Java 的类加载机制。

            oh,no,上面这段话说得很笼统,欠好了解,对不对,我来举个比方。

            String cmower = new String("缄默沉静王二");

            上面这段代码运用了 new 关键字来实例化一个字符串方针,那么这时分,就会调用 String 类的结构办法对 cmower 进行实例化。

            03、类加载器

            聊完类加载进程,就不得不聊聊类加载器。

            一般来说,Java 程序员并不需求直接同类加载器进行交互。JVM 默许的行为就现已满意满意大多数状况的需求了。不过,假如遇到了需求和类加载器进行交互的状况,而对类加载器的机制又不是很了解的话,就不得不花很多的时刻去调试 ClassNotFoundException 和 NoClassDefFoundError 等反常。

            关于恣意一个类,都需求由它的类加载器和这个类自身一同确认其在 JVM 中的唯一性。也便是说,假如两个类的加载器不同,即便两个类来源于同一个字节码文件,那这两个类就必定不相等(比方两个类的 Class 方针不 equals )。

            站在程序员的视点来看,Java 类加载器可以分为三种。

            1)发动类加载器(Bootstrap Class-Loader),加载 jre/lib 包下面的 jar 文件,比方说常见的 rt.jar。

            2)扩展类加载器(Extension or Ext Class-Loader),加载 jre/lib/ext 包下面的 jar 文件。

            3)运用类加载器(Application or App Clas-Loader),依据程序的类途径(classpath)来加载 Java 类。

            来来来,经过一段简略的代码了解下。

            public class Test {
            public static void main(String[] args) {
            ClassLoader loader = Test.class.getClassLoader();
            while (loader != null) {
            System.out.println(loader.toString());
            loader = loader.getParent();
            }
            }
            }

            每个 Java 类都维护着一个指向界说它的类加载器的引证,经过 类名.class.getClassLoader()可以获取到此引证;然后经过 loader.getParent() 可以获取类加载器的上层类加载器。

            这段代码的输出成果如下:

            sun.misc.Launcher$AppClassLoader@73d16e93
            sun.misc.Launcher$ExtClassLoader@15db9742

            榜首行输出为 Test 的类加载器,即运用类加载器,它是 sun.misc.Launcher$AppClassLoader类的实例;第二行输出为扩展类加载器,是 sun.misc.Launcher$ExtClassLoader 类的实例。那发动类加载器呢?

            按理说,扩展类加载器的上层类加载器是发动类加载器,但在我这个版别的 JDK 中, 扩展类加载器的 getParent() 回来 null 。所以没有输出。

            04、双亲派遣模型

            假如以上三品种加载器不能满意要求的话,程序员还可以自界说类加载器(承继 java.lang.ClassLoader 类),它们之间的层级联系如下图所示。

            这种层次联系被称作为 双亲派遣模型 :假如一个类加载器收到了加载类的恳求,它会先把恳求托付给上层加载器去完结,上层加载器又会托付上上层加载器,一直到最顶层的类加载器;假如上层加载器无法完结类的加载作业时,当时类加载器才会测验自己去加载这个类。

            PS:双亲派遣模型忽然让我联想到朱元璋同志,这个同志当上了皇帝之后连宰相都不要了,一切的工作都亲力亲为,只需自己没精力没时刻做的事才交给大臣们去干。

            运用双亲派遣模型有一个很明显的优点,那便是 Java 类跟着它的类加载器一同具有了一种带有优先级的层次联系,这关于确保 Java 程序的安稳运作很重要。

            上文中曾说到,假如两个类的加载器不同,即便两个类来源于同一个字节码文件,那这两个类就必定不相等——双亲派遣模型可以确保同一个类终究会被特定的类加载器加载。

            05、终究

            硬着头皮翻看了很多的材料,而且着手去研讨今后,我发现自己居然对 Java 类加载机制(JVM 将类的信息动态添加到内存并运用的一种机制)不那么抵抗了——真是蛮美妙的一件事啊。

            或许学习就应该是这样,只需你勇于应战自己,就能收成常识——就像山就在那里,只需你肯攀爬,就能抵达山顶。

            end:假如你觉得本文对你有协助的话,记住关注点赞转发,你的支撑便是我更新动力。

            请关注微信公众号
            微信二维码
            不容错过
            Powered By Z-BlogPHP