深入研究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文件要跨平台的关键。

时间: 2024-10-17 03:49:32

深入研究Java类装在机制的相关文章

Java类的多态机制

Java中将一个方法调用同一个方法主体关联起来被称作绑定.绑定分为前期绑定和后期绑定.前期绑定是在编译器决定的,而后期绑定是在程序运行时决定的.Java中除了static方法和final方法(private方法也是final方法,只不过是隐式的为final)之外,其他所有的方法都是后期绑定.Java类的多态指的是当将子类向上转型为父类型并调用父类型中相应的方法时,多态机制会根据动态绑定自动判断出调用相应的子类的方法.也就是说多态机制的存在的基础是子类实现了对父类中相应方法的函数覆盖.比如有一个S

深入研究java.lang.Runtime类

深入研究java.lang.Runtime类 一.概述      Runtime类封装了运行时的环境.每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接.      一般不能实例化一个Runtime对象,应用程序也不能创建自己的 Runtime 类实例,但可以通过 getRuntime 方法获取当前Runtime运行时对象的引用.      一旦得到了一个当前的Runtime对象的引用,就可以调用Runtime对象的方法去控制Java虚拟机的状态和行为.

深入研究java.lang.ThreadLocal类

深入研究java.lang.ThreadLocal类 一.概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量).也许把它命名为ThreadLocalVar更加合适.线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是Java中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副

深入研究java.lang.Runtime类(转)

一.概述      Runtime类封装了运行时的环境.每个 Java 应用程序都有一个 Runtime 类实例,使应用程序能够与其运行的环境相连接.      一般不能实例化一个Runtime对象,应用程序也不能创建自己的 Runtime 类实例,但可以通过 getRuntime 方法获取当前Runtime运行时对象的引用.      一旦得到了一个当前的Runtime对象的引用,就可以调用Runtime对象的方法去控制Java虚拟机的状态和行为.       当Applet和其他不被信任的代

深入研究Java类加载机制

类加载是Java程序运行的第一步,研究类的加载有助于了解JVM执行过程,并指导开发者采取更有效的措施配合程序执行. 研究类加载机制的第二个目的是让程序能动态的控制类加载,比如热部署等,提高程序的灵活性和适应性. 一.简单过程 Java程序运行的场所是内存,当在命令行下执行: java HelloWorld 命令的时候,JVM会将HelloWorld.class加载到内存中,并形成一个Class的对象HelloWorld.class. 其中的过程就是类加载过程: 1.寻找jre目录,寻找jvm.d

深入研究JAVA ThreadLocal类

深入研究java.lang.ThreadLocal类 一.概述 ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是 threadlocalvariable(线程局部变量).也许把它命名为ThreadLocalVar更加合适.线程局部变量 (ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是Java中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其它线程

转发 深入研究java.lang.Runtime类

转发 深入研究java.lang.Runtime类 前言:Java的类库日益庞大,所包含的类和接口也不计其数.但其中有一些非常重要的类和接口,是Java类库中的核心部分.常见的有String.Object.Class.Collection.ClassLoader.Runtime.Process...,熟悉这些类是学好Java的基础.而这些类一般不容易理解,需要做深入的研究和实践才能掌握.下面是我对这些类理解和使用的一些总结.欢迎你在阅读后将你宝贵的意见和读后感留下! 一.概述      Runt

如何利用缓存机制实现JAVA类反射性能提升30倍

一次性能提高30倍的JAVA类反射性能优化实践 文章来源:宜信技术学院 & 宜信支付结算团队技术分享第4期-支付结算部支付研发团队高级工程师陶红<JAVA类反射技术&优化> 分享者:宜信支付结算部支付研发团队高级工程师陶红 原文首发于宜信支付结算技术团队公号:野指针 在实际工作中的一些特定应用场景下,JAVA类反射是经常用到.必不可少的技术,在项目研发过程中,我们也遇到了不得不运用JAVA类反射技术的业务需求,并且不可避免地面临这个技术固有的性能瓶颈问题. 通过近两年的研究.尝

jvm系列(一):java类的加载机制

java类的加载机制 原文:http://www.cnblogs.com/ityouknow/p/5603287.html 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构.类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口. 类加载器并不需要等到某个