zoukankan      html  css  js  c++  java
  • java架构之路-(JVM优化与原理)JVM类的加载机制

        话不多说,先上图。

     ***.class文件执行大概就是这样来走的。我们都知道我们的java文件经过编译以后会生成对应的class文件。先经过类装载子系统,然后塞进运行时内存模型的元空间,开始执行方法,对象放在堆,线程开辟栈空间,程序计数器控制执行顺序。字节码执行引擎整体调控程序计数器,走你。。。大概就是这样的。我们先来看一下类装载子系统是如何工作的。

      类装载子系统大概分为,验证->准备->解析->初始化。笼统的来说就这个4个步骤。

    1,验证:验证我们的编译文件(字节码文件)是否正确。

    2,准备:给予类的静态常量开辟堆空间。并且赋予默认值。对象也在这个时候放置在堆空间,并且给予空值。

    3,解析:将符号引用替换为直接引用,该阶段会把一些静态方法(符号引用,比如main()方法)替换为指向数据所存内存的指针或句柄等(直接引用),这是所谓的静态链接过程(类加载期间完成),动态链接是在程序运行期间完成的将符号引用替换为直接引用。就像是我们把main转化为001,将()转化为002,将这一系列的编码存在堆上。

    4,初始化,将第3步的静态常量(或对象)赋值,执行静态代码块。

    类的加载器大致分为,启动类加载器,扩展类加载器,应用类加载器和自定义加载器,后面我们会说如何实现自己的类加载器。

    启动类加载器是用来加载java自身的lib包的。用C语言实现的,我们是看不到的。

    扩展类加载器顾名思义,是加载java的扩展包的。加载ext包下的jar包

    然后就是我们的应用加载器,来执行我们一行行代码的。

    最后才是我们的自定义加载器。我来看一段代码。

    import com.sun.crypto.provider.DESKeyFactory;
    
    public class Main {
    
        public static void main(String[] args) {
            System.out.println(String.class.getClassLoader());
            System.out.println(DESKeyFactory.class.getClassLoader().getClass().getName());
            System.out.println(Main.class.getClassLoader().getClass().getName());
        }
    }

    输入如下:

    null
    sun.misc.Launcher$ExtClassLoader
    sun.misc.Launcher$AppClassLoader
    
    Process finished with exit code 0

    三种加载器就是这样的。

     双亲委派机制:

      我们知道一个基础的知识,就是我们新建的java.lang.String是无法加载的,就是加载过程的双亲委派机制限制了我们自定义重写java本来的代码。

    双亲委派是为了阻止我们重写java内部的类,做到了沙箱安全的目的。

      大概就是这样来实行的。上图:

    自定义加载器会优先拿到要加载的文件,但是他不会去马上加载。而是直接交给应用类加载器,应用类加载器也不会管,继续向上走,交给扩展类加载器,他也不管,继续向上走,交给启动类加载器,没办法了,启动类加载器没法继续向上交付了。自己先试试可以加载吗?可以加载就加载,加载不了退返给扩展类加载器,扩展类看到是推回来的,试试吧。可以加载吗?可以加载就加载,加载不了退返给应用类加载器,应用类加载器可以加载就加载,加载不了退返给自定义加载器。这样一个由下到上,谁也不管。逐个去尝试往下推的方法去加载。好久就是为了防止你重写java内部的类。

      这里简单说一下自定义加载器。

    我们只要重写com.sun.org.apache.bcel.internal.util;包下的ClassLoader类的findClass方法,最后调用defineClass方法。就可以实现我们的自定义加载器。

      这回我们再回过头来看上一篇博客的tomcat打破双亲委派机制也就懂得是怎么回事了吧。不懂的评论留言吧。就说到这里,我们下一次说一下jvm运行时内存模型那一块。

     写的这么不好的文章能坚持读到最下面确实挺不易的,贡献一个小技巧,来看类是否真的被加载了。

    最进弄了一个公众号,小菜技术,欢迎大家的加入

  • 相关阅读:
    UltraEdit语法高亮解决办法
    tcpdump命令格式及使用
    VS tricks
    git ready
    [FirefoxPlugin]Print pages to Pdf
    Searching and Navigating Code in VS 2010 (VS 2010 and .NET 4.0 Series)
    How to avoid StepInto unnecessary code area?
    Search and Navigation Tips/Tricks with Visual Studio
    squashing commits with rebase
    【原创】钻石继承与虚继承
  • 原文地址:https://www.cnblogs.com/cxiaocai/p/11483629.html
Copyright © 2011-2022 走看看