转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6536048.html 

虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析初始化,最终成为被虚拟机直接使用的Java对象,这就是JVM的类加载机制。

Java天生的可动态扩展的语言特性就是依赖运行期的动态加载动态连接实现的。

一:类的生命周期

类的生命周期包括7个部分:加载——验证——准备——解析——初始化——使用——卸载

其中,验证——准备——解析  称为连接阶段。除了解析外,其他阶段是顺序发生的,而解析可以与这些阶段交叉进行,因为Java支持动态绑定(晚期绑定),需要运行时才能确定具体类型。

二:类的初始化触发

类的加载机制没有明确的触发条件,但是有5种情况下必须对类进行初始化,那么 加载——验证——准备 就必须在此之前完成了。

1:new、getstatic、putstatic、invokestatic这4个  字节码指令  时对类进行初始化(即:实例化对象、读写静态对象、调用静态方法时,进行类的初始化);

2:使用反射机制对类进行调用时,进行类的初始化;

3:初始化一个类,其父类没有初始化时,先初始化其父类;

4:虚拟机启动时,初始化一个执行主类;

5:使用JDK1.7的动态语言支持时,如果MethodHandle实例的解析结果为REF_getstatic、REF_putstatic、REF_invokestatic的方法句柄(即:读写静态对象或者调用静态方法),则初始化该句柄对应类;

一般,以上5种情况最常见的是前三种:实例化对象、读写静态对象、调用静态方法、反射机制调用类、调用子类触发父类初始化

三:类的加载过程

从用户角度来说,类(对象)的生命周期只需笼统理解为“加载——使用——卸载”即可,无需太过深入。所以,这里的类加载过程就是我们说的 加载——验证——准备——解析——初始化  这五个使用前的阶段。

1:加载

加载阶段,虚拟机需要完成三件事:通过类名字获取类的二进制字节流——将字节流的内容转存到方法区——在内存中生成一个Class对象作为该类方法区数据的访问入口

其中,第一步:通过类名获取类的二进制字节流是通过类加载器来完成的。其加载过程使用“双亲委派模型”:

类加载器的层次结构为:

启动类加载器:加载系统环境变量下JAVA_HOME/lib目录下的类库。

扩展类加载器:加载JAVA_HOME/lib/ext目录下的类库。

应用程序类加载器(系统类加载器):加载用户类路径Class_Path指定的类库。(我们可以在使用第三方插件时,把jar包添加到ClassPath后就是使用了这个加载器)

自定义加载器:如果需要自定义加载时的规则(比如:指定类的字节流来源、动态加载时性能优化等),可以自己实现类加载器。

双亲委派模型是指:当一个类加载器收到类加载请求时,不会直接加载这个类,而是把这个加载请求委派给自己父加载器去完成。如果父加载器无法加载时,子加载器才会去尝试加载。

采用双亲委派模型的原因:避免同一个类被多个类加载器重复加载。

2:验证

确保class文件的二进制字节流中包含的信息符号虚拟机要求,包括:文件格式验证、元数据验证(数据语义分析)、字节码验证(数据流语义合法性)、符号引用验证(符号引用的匹配性校验,确保解析能正确执行)

3:准备

类变量(静态变量)方法区分配内存,并设置零值。注意:这里是类变量,不是实例变量,实例变量是对象分配到堆内存时根据运行时动态生成的。

4:解析

把常量池中的符号引用解析为直接引用:根据符号引用所作的描述,在内存中找到符合描述的目标并把目标指针指针返回。

5:初始化

真正开始执行Java程序代码,该步执行<clinit>方法根据代码赋值语句,对 类变量和其他资源  进行初始化赋值。

<clinit>方法:编译器自动收集类中所有  类变量的赋值语句和静态语句合并而成,收集的顺序是在程序代码出现的顺序。所以,静态语句中只能访问到定义在静态语句块之前的变量,在其之后的变量可以赋值(相当于新建并赋值了)但不可以访问(因为还没出现)。

注:由此步我们就可以得知,我们在分析向上转型的例子时的程序代码的运行顺序了:父类静态内容——子类静态内容——父类构造——子类构造——子类方法 。

在经历了上面5步“加载”阶段后,才真正地可以使用class对象或者使用实例对象。使用过后,不再需要用到该类的class对象或者实例对象时,就会把类卸载掉(发生在方法区的垃圾回收:无用类的卸载)。

四:对象的生命周期

对象是由类创建出来的,所以对象的生命周期就是包含在类的生命周期中:

类加载(5步)——创建类的实例对象——使用对象——对象回收——类卸载

JVM类加载机制与对象的生命周期的更多相关文章

  1. 理解JVM——类加载机制

    我们在编写Java程序之后,会通过编译器得到一个class文件,这个class文件是如何与JVM进行配合的呢?类中的信息是如何变成JVM可以使用的Java类型呢?这些都是类加载机制做到的. 虚拟机把描 ...

  2. 管中窥豹——从对象的生命周期梳理JVM内存结构、GC调优、类加载、AOP编程及性能监控

    如题,本文的宗旨既是透过对象的生命周期,来梳理JVM内存结构及GC相关知识,并辅以AOP及双亲委派机制原理,学习不仅仅是海绵式的吸收学习,还需要自己去分析why,加深对技术的理解和认知,祝大家早日走上 ...

  3. JVM的内存管理、对象的生命周期、内存泄漏

    1 JVM内存 分为“堆”.“栈”和“方法区”三个区域,分别用于存储不同的数据 1.1 堆 JVM在其内存空间开辟一个称为”堆”的存储空间,这部分空间用于存储使用new关键字所创建的对象. 1.2 栈 ...

  4. Java虚拟机(三)垃圾标记算法与Java对象的生命周期

    前言 这一节我们来简单的介绍垃圾收集器,并学习垃圾标记的算法:引用计数算法和根搜索算法,为了更好的理解根搜索算法,会在文章的最后介绍Java对象在虚拟机中的生命周期. 1.垃圾收集器概述 垃圾收集器( ...

  5. Java虚拟机(四):JVM类加载机制

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

  6. JVM类加载机制(转)

    原文出自:http://www.cnblogs.com/ityouknow/p/5603287.html 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运 ...

  7. Android动态加载--JVM 类加载机制

    动态加载,本质上是通过JVM类加载机制将插件模块加载到宿主apk中,并通过android的相关运行机制,实现插件apk的运行.因此熟悉JVM类加载的机制非常重要. 类加载机制:虚拟机把描述类的数据从C ...

  8. 深入理解JVM虚拟机6:深入理解JVM类加载机制

    深入理解JVM类加载机制 简述:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 下面我们具体 ...

  9. JVM05——JVM类加载机制知多少

    我们已经讲过 JVM 相关的很多常见知识点,感兴趣的朋友可以在我的往期文章中查看.接下来将继续为各位带来 JVM 类加载机制.关注我的公众号「Java面典」了解更多 Java 相关知识点. 类生命周期 ...

随机推荐

  1. svn: E155015: 提交失败(细节如下) 解决办法

    svn 出现冲突是经常发生的事,最近改用命令操作svn,用界面电脑有些反应慢 出现冲突使用svn 命令肯定也是可以解决的: 查看警告信息提示冲突的文件,执行 svn resolved <文件名& ...

  2. information_schema系列九

    information_schema系列九   1:INNODB_SYS_FOREIGN 这个表存储的是INNODB关于外键的元数据信息 Column name Description ID 外键的名 ...

  3. KOL:Key Opinion Leader

    什么是关键意见领袖 在营销学上,为各厂家宣传的专家或权威被称为“关键意见领袖(Key Opinion Leader),通常被定义为:拥有更多.更准确的产品信息,且为相关群体所接受或信任,并对该群体的购 ...

  4. go语言之进阶篇通过map生成json

    1.通过map生成json 示例1: package main import ( "encoding/json" "fmt" ) func main() { / ...

  5. 【BLE】CC2541之发现服务与特征值

    一.简介 本文以SimpleBLECentral工程为例,解析CC2541作为主机时是如何发现从机的服务和特征值的. 二.实验平台 协议栈版本:BLE-CC254x-1.4.0 编译软件:IAR 8. ...

  6. ds18b20驱动及应用程序

    ---------------------------------------------------------------------------------------------------- ...

  7. 读书笔记,《深入理解java虚拟机》,第二章,java内存区域与内存溢出异常

    第二节,运行时数据区域.    在这个章节中,作者给出了一个java虚拟机运行时数据区的框图,图的左侧是方法区和堆,这两个数据区是所有的线程所共享的.然后是虚拟机栈.本地方法栈.还有程序计数器,这三个 ...

  8. ES6 主要的新特性

    本文基于lukehoban/es6features ,同时参考了大量博客资料,具体见文末引用. ES6(ECMAScript 6)是即将到来的新版本JavaScript语言的标准,代号harmony( ...

  9. js改变iframe 的src地址

    <script> function dizhi(){ document.getElementById("aaa").src='http://www.sohu.com' ...

  10. set练习

    #include <iostream> #include <set> #include <vector> using namespace std; int main ...