zoukankan      html  css  js  c++  java
  • 深入研究Java类装载机制

    目录

    1.为什么要研究java类装在机制?

    2.了解类装载机制,对于我们在项目开发中有什么作用?

    3.装载实现细节。

    4.总结

    一、为什么药研究Java类装载机制

      java类加载机制,便于我们使用自定义类加载器;深入理解,对于理解编译原理也有很大帮助。

    二、了解类装载机制,在我们项目开始中的应用

      在项目中,我们可以使用自定义类加载器,可以帮助我们做如下操作:

      (1)加密。java代码很容易被反编译,如果你需要把自己的代码进行加密,可以先将编译后的代码用某种加密算法加密,然后实现自己的类加载器,负责将这段加密后的代码还原,以被操作系统所识别。这样,别人看到的是加密后的.class文件,无法进行反编译。

      (2)从指定来源加载。如果字节码文件不是采用标准的方式来加载代码,可能从数据库或者网络上加载,就需要自定义类加载器,从指定路径加载类文件。

      (3)性能。基于实际情况,动态创建代码并执行。

    三、java类装载机制原理

      Java程序被执行的流程图如下:Java源文件(*.java)==》java编译器==》字节码文件(*.class)==》类装载器==》字节码校验器==》解释器==》操作系统,整个文件被load到内存区,一系列动作之后,最终形成了操作系统可以识别的代码,操作系统找到main方法开始执行。其中,heap(new出来的东西放在里面)、stack(局部变量)、data segment(静态变量或字符串常量)、code segment(存放代码)。


    如上图所示,public static void main(String args[])被编译到操作系统中后,作为程序的入口,开始执行。接下来分析一下这个过程

       

    如左图所示,JRE提供的jar包,正如名字一样,它提供了java运行时环境。右图是Hello World被编译为.class文件后的效果。一个java类被加载的过程如下:

    1、使用命令执行javac Main.java,生成Main.class文件;执行java Main命令,JVM会将Main.class加载到内存中,并形成一个class的对象Main.class。关于Class对象和Object对象的区别,参考附录一。

    2、JVM将Main.class加载到内存如下:首先,寻找JRE目录,找到jvm.dll,并初始化JVM;然后产生一个Bootstrap Loader(启动类加载器),Bootstrap Loader自动加载Extended Loader(标准扩展类加载器),并将其父loader设置为Bootstrap loader;Bootstrap Loader自动加载Appclass loader(系统类加载器),并将其父loader设为Extended Loader。最后由Appclass loader加载Main类。

    即:Bootstrap loader==》Extended Loader==》Appclass loader(*.class文件说明见附录二)

    3、接着第二部,在装载过程中,如编译原理中所描述,要依次进行如下步骤。类加载器appclass loader寻找类的字节码文件Main.class,并且构造出类的JVM内部表示的对象组件。

      (1)装载,查找和导入class文件。

      (2)链接,把二进制数据合并到JRE中。

        (a)校验:检查载入class文件数据的正确性

        (b)准备:给类的静态变量分配存储空间

        (c)解析:将符号引用转成直接引用

      (3)初始化,对类的静态变量,静态代码块进行初始化操作。

    4、常用方法:

     

    ClassLoader loader = Main.class.getClassLoader(); 
    loader.loadClass("Main"); 
    
    类加载有三种方式:
    1、命令行启动应用时候由JVM初始化加载
    2、通过Class.forName()方法动态加载
    3、通过ClassLoader.loadClass()方法动态加载

     

    四、总结

      类的加载,最终从硬盘加载到内存当中,变成基于操作系统可以识别的二进制文件流来执行,因此,优化代码,需要掌握JVM在内存当中的布局。

    附录一:Object和Class两个类之间的区别

      Object是所有类的父类,所有类当然也包括Class类。所以,Object类是Class类的父类。

    private Class(ClassLoader loader) {
        // Initialize final field for classLoader.  The initialization value of non-null
        // prevents future JIT optimizations from assuming this final field is null.
        classLoader = loader;
    }

      Class这个类,构造方法是私有的。所以不能显示的new 一个class对象。它是用来描述一个对象的元信息的。

    附录二:*.class文件说明

      Java的Class文件是有8个字节为基础的字节流构成的,这些字节流之间都严格按照规定的顺序排列,并且字节之间不存在任何空隙,对于超过8个字节的数据,将按照Big-Endian的顺序存储的,也就是说高位字节存储在低的地址上面,而低位字节存储到高地址上面,其实这也是class文件要跨平台的关键。

  • 相关阅读:
    English 2
    速算24点
    心理学1
    从微服务到函数式编程
    034 01 Android 零基础入门 01 Java基础语法 04 Java流程控制之选择结构 01 流程控制概述
    033 01 Android 零基础入门 01 Java基础语法 03 Java运算符 13 运算符和表达式知识点总结
    032 01 Android 零基础入门 01 Java基础语法 03 Java运算符 12 运算符和if-else条件语句的综合案例——闰年问题
    031 01 Android 零基础入门 01 Java基础语法 03 Java运算符 11 运算符的优先级
    030 01 Android 零基础入门 01 Java基础语法 03 Java运算符 10 条件运算符
    029 01 Android 零基础入门 01 Java基础语法 03 Java运算符 09 逻辑“非”运算符
  • 原文地址:https://www.cnblogs.com/RunForLove/p/5538090.html
Copyright © 2011-2022 走看看