服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服务器之家 - 编程语言 - JAVA教程 - 从JVM分析Java的类的加载和卸载机制

从JVM分析Java的类的加载和卸载机制

2020-01-15 14:13圣骑士Wind的博客 JAVA教程

这篇文章主要介绍了从JVM分析Java的类的加载和卸载机制,讲解了Java类的声明周期,需要的朋友可以参考下

从JVM分析Java的类的加载和卸载机制

 

类的加载
  类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。

  加载.class文件的方式:

  1.从本地系统中直接加载

  2.通过网络下载.class文件

  3.从zip,jar等归档文件中加载.class文件

  4.从专有数据库中提取.class文件

  5.将Java源文件动态编译为.class文件

  类的加载的最终产品是位于堆区中的Class对象。

  Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。

从JVM分析Java的类的加载和卸载机制

类加载器
  加载器有两种类型:

  1.Java虚拟器自带的加载器

        根类加载器(Bootstrap)

        扩展类加载器(Extension)

        系统类加载器或称应用加载器(System)

  后两种加载器是Java实现的,根类加载器是C++写的,程序员无法在Java代码中获得该类。

  2.用户自定义的类加载器

        java.lang.ClassLoader的子类

        用户可以定制类的加载方式 

  类加载器并不需要等到某个类被首次主动使用时再加载它。

  JVM规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类时才报告错误(LinkageError)。如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误。

类的卸载机制
类的生命周期
  当Sample类被加载、连接和初始化后,它的生命周期就开始了。

  当代表Sample类的Class对象不再被引用,即不可触及时,Class对象就会结束生命周期,Sample类在方法区内的数据也会被卸载,从而结束Sample类的生命周期。

  由此可见,一个类何时结束生命周期,取决于代表它的Class对象何时结束生命周期。

引用关系
  加载器和Class对象:

  在类加载器的内部实现中,用一个Java集合来存放所加载类的引用。

  另一方面,一个Class对象总是会引用它的类加载器。调用Class对象的getClassLoader()方法,就能获得它的类加载器。

  由此可见,Class实例和加载它的加载器之间为双向关联关系。

  类、类的Class对象、类的实例对象:

  一个类的实例总是引用代表这个类的Class对象。

  在Object类中定义了getClass()方法,这个方法返回代表对象所属类的Class对象的引用。

  此外,所有的Java类都有一个静态属性class,它引用代表这个类的Class对象。

 

类的卸载
  由Java虚拟机自带的类加载器所加载的类,在虚拟机的生命周期中,始终不会被卸载。

  前面介绍过,Java虚拟机自带的类加载器包括根类加载器、扩展类加载器和系统类加载器。

  Java虚拟机本身会始终引用这些类加载器,而这些类加载器则会始终引用它们所加载的类的Class对象,因此这些Class对象始终是可触及的。

  由用户自定义的类加载器加载的类是可以被卸载的。

具体例子

从JVM分析Java的类的加载和卸载机制

loader1变量和obj变量间接应用代表Sample类的Class对象,而objClass变量则直接引用它。

  如果程序运行过程中,将上图左侧三个引用变量都置为null,此时Sample对象结束生命周期,MyClassLoader对象结束生命周期,代表Sample类的Class对象也结束生命周期,Sample类在方法区内的二进制数据被卸载。

  当再次有需要时,会检查Sample类的Class对象是否存在,如果存在会直接使用,不再重新加载;如果不存在Sample类会被重新加载,在Java虚拟机的堆区会生成一个新的代表Sample类的Class实例(可以通过哈希码查看是否是同一个实例)。

延伸 · 阅读

精彩推荐
  • JAVA教程Java添加事件监听的四种方法代码实例

    Java添加事件监听的四种方法代码实例

    这篇文章主要介绍了Java添加事件监听的四种方法代码实例,本文直接给出代码示例,并用注释说明,需要的朋友可以参考下 ...

    junjie2962019-11-29
  • JAVA教程java全角、半角字符的关系以及转换详解

    java全角、半角字符的关系以及转换详解

    如果搞明白了Java中全角字符和半角字符之间的关系 那他们之间的转换根本就不是个事. 全角字符与半角字符的关系 可以通过下面的程序看看Java中所有字符...

    java技术网4752019-10-22
  • JAVA教程JavaMe开发自适应滚动显示

    JavaMe开发自适应滚动显示

    我们常看到一些滚动显示的实例,比如UC浏览器中,显示网页的内容。当内容比较多时,采用滚动分页显示是合理的。在Canvas中绘图中,多余的内容被截断...

    lijiao1522020-01-06
  • JAVA教程Jar打包用法详解

    Jar打包用法详解

    这篇文章主要介绍了Jar打包用法,详解分析了jar打包命令的各种常见用法及参数含义,非常具有实用价值,需要的朋友可以参考下 ...

    shichen20142452019-12-06
  • JAVA教程图解Eclipse j2ee开发环境的搭建过程

    图解Eclipse j2ee开发环境的搭建过程

    这篇文章以图文结合的方式介绍了Eclipse j2ee开发环境的搭建过程,内容很详细,每一个步骤都有对应的操作截图,需要的朋友可以参考下 ...

    mayabin2562020-01-02
  • JAVA教程Java中StringBuffer和StringBuilder区别

    Java中StringBuffer和StringBuilder区别

    这篇文章主要介绍了Java中StringBuffer和StringBuilder区别,本文只介绍了它们之间的核心区别,需要的朋友可以参考下 ...

    junjie3312019-12-21
  • JAVA教程Java实现Map集合二级联动示例

    Java实现Map集合二级联动示例

    Java实现Map集合二级联动示例,需要的朋友可以参考下 ...

    java教程网3152019-11-11
  • JAVA教程Spring创建Bean的6种方式详解

    Spring创建Bean的6种方式详解

    这篇文章主要介绍了Spring创建Bean的6种方式详解,本文讲解了在Spring 应用中创建Bean的多种方式,包括自动创建,以及手动创建注入方式,实际开发中可以根...

    冬眠的山谷2292019-06-25