类被加载到虚拟机内存开始,到卸载出内存为止,经历了:加载->验证->准备->解析->初始化->使用->卸载 这七个过程

  1. 加载

在加载阶段,虚拟机要完成三件事:

(1)    通过一个类的全限定名来获取定义此类的二进制字节流;

(2)    将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;

(3)    在Java堆中生成一个代表这个类的java.lang.Class对象,作为方法区这些数据的访问入口。

2.验证

验证是链接阶段的第一步,目的是为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机的自身安全。

验证阶段大致要经历四个过程:文件格式验证,元数据验证,字节码验证和符号引用验证。

3.准备

准备阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些内存都将在方法区中进行分配。通常情况下,初始化为零值。

假设有个变量定义如下:

Public static int value=123;

则在准备阶段过后它的值不是123而是0,因为这时候尚未开始执行任何java方法,而把value赋值为123的putstatic指令是程序被编译后,存放在类构造器<clinit>()方法之中,故把value赋值为123的动作将在初始化阶段才会被执行。

有些特殊情况,如类静态变量的属性表中存在ConstantValue属性,则在准备阶段变量就会被初始化为ConstantValue属性所指的值。

若上例中变量定义改为:

Public static final int value=123;

编译时javac将会为value生成ConstantValue属性,在准备阶段虚拟机就会根据ConstantValue的设置将value赋值为123。

4.解析

解析阶段是虚拟机将常量池内的符号引用替换为直接引用的过程。

符号引用:以一组符号来描述所引用的目标,符号可以是任何形式的字面量,主要使用时能无歧义的表示即可(符号引用与虚拟机的内存布局无关,引用的目标并不一定已经加载到内存中);

直接引用:可以是直接指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄(直接引用与虚拟机实现的内存布局相关,同一个符号引用在不同的虚拟机实例上翻译出来的直接引用一般不会相同)。如果有了直接引用,则引用的目标必定已经在内存中存在。

5.初始化

前几个阶段主要是由虚拟机主导和控制,到了初始化阶段才真正开始执行类中定义的Java程序代码(或是字节码)。

初始化阶段是执行类构造器<clinit>()方法的过程

(1)<clinit>()方法是由编译器自动收集类中的所有类变量的赋值动作和静态语句块(static{})中的语句合并产生的,编译器收集的顺序是由语句在源文件中出现的顺序所决定的,静态语句块中只能访问到定义在静态语句块之前的变量,定义在它之后的变量。在前面的静态语句块中可以赋值,但不能访问。

(2)<clinit>()方法与类的构造函数(或者说实例构造器<init>()方法)不同,它不需要显式地调用父类的构造器,虚拟机后保证子类的<clinit>()方法在执行之前,父类的<clinit>()方法已经执行完毕。因此在虚拟机中第一个被执行的<clinit>()方法的类肯定是java.lang.Object

(3)由于父类的<clinit>()方法先执行,也就意味着父类中定义的静态语句块要优先于子类的变量赋值操作。

class Parent{

public static int A=1;

static{

A=2;

}

}

class Sub extends Parent{

public static int B=A;

}

public class clinitTest {

public static void main(String []args){

System.out.println(Sub.B);

}

}

上面的程序运行结果为:2

(4)<clinit>()方法对于类或接口来说并不是必须的,如果一个类中没有静态语句块,也没有对变量的赋值操作,那么编译器可以不为这个类生成<clinit>()方法。

(5)接口中不能使用静态语句块,但仍然有变量初始化的赋值操作,因此接口与类一样都会生成<clinit>()方法。但接口与类不同的是,执行接口的<clinit>()方法不需要先执行父接口的<clinit>()方法,只有当父接口中定义的变量被使用时,父接口才会被初始化。另外,接口的实现类在初始化时也一样不会执行接口的<clinit>()方法。

(6)虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确地加锁和同步,如果多个线程同时去初始化一个类,那么只会有一个线程去执行这个类的<clinit>()方法,其他线程都需要阻塞等待,知道活动线程执行<clinit>()方法完毕。

转载于:https://www.cnblogs.com/hello--the-world/archive/2012/07/20/2601348.html

Java虚拟机对类加载的处理机制相关推荐

  1. Java虚拟机中类加载机制详解

    Java虚拟机中类加载机制详解 1,什么是java类加载机制 **首先在java中,是通过编译来生成.class文件(可能在本地,或者网页下载),java的类加载机制就是 将这些.class文件加载到 ...

  2. 深入Java虚拟机之类加载

    深入Java虚拟机_ClassLoader 类加载器深入剖析 Java虚拟机与程序的生命周期 在如下几种情况下,Java虚拟机将结束生命周期 执行了System.exit()方法 程序正常执行结束 程 ...

  3. 《深入理解Java虚拟机》阅读——垃圾回收机制

    <深入理解Java虚拟机>阅读--垃圾回收机制 前言 why--为什么需要垃圾回收 what--垃圾回收做些什么 where--去哪里回收垃圾 how--垃圾回收是怎么做的 垃圾是否要回收 ...

  4. 深入理解Java虚拟机(类加载机制)

    文章首发于微信公众号:BaronTalk 上一篇文章我们介绍了「类文件结构」,这一篇我们来看看虚拟机是如何加载类的. 我们的源代码经过编译器编译成字节码之后,最终都需要加载到虚拟机之后才能运行.虚拟机 ...

  5. 深入理解Java虚拟机——JVM类加载机制(类加载过程和类加载器)

    一.什么是类加载机制? 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 二.类加载的时机 类 ...

  6. Java虚拟机:类加载机制详解

    版权声明:本文为博主原创文章,转载请注明出处,欢迎交流学习! 大家知道,我们的Java程序被编译器编译成class文件,在class文件中描述的各种信息,最终都需要加载到虚拟机内存才能运行和使用,那么 ...

  7. 没有为 ucrtbase.dll 加载符号_深入理解Java虚拟机(类加载机制)

    上一篇文章我们介绍了「类文件结构」,这一篇我们来看看虚拟机是如何加载类的. 我们的源代码经过编译器编译成字节码之后,最终都需要加载到虚拟机之后才能运行.虚拟机把描述类的数据从 Class 文件加载到内 ...

  8. 获取虚拟机的唯一标识_JVM笔记:Java虚拟机的类加载机制(附详细思维导图)...

    虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 类加载的流程 类从被加载到虚拟机内存中开始, ...

  9. 深入理解Java虚拟机02—类加载机制

    文章目录 1 类加载过程 1.1 加载 1.2 连接 1.2.1 验证 1.2.2 准备 1.2.3 解析 1.3 初始化 2 类加载器 2.1 类加载器 2.2 双亲委派模型 2.3 破坏双亲委派模 ...

最新文章

  1. showModalDialog关闭子窗口,并刷新父窗口
  2. 如何将现有的非空目录转换为Git工作目录并将文件推送到远程存储库
  3. python基础教程第三版电子版百度云-《python基础教程第三版》高清版PDF免费下载...
  4. Nginx 源码分析:ngx_hash_t(上)
  5. keras从入门到放弃(二十二)一维卷积处理 RNN文本分类
  6. android传递布局到下个页面,浅入浅出Android(017):当前Activity向下一个Activity切换,并传递数据...
  7. Win10 通过升级安装完成后出现了中文字体忽大忽小的问题解决。
  8. word插入参考文献、目录及公式对齐方法
  9. java oracle sql 参数_oracle pl/sql之在java中调用带有输入输出参数的oracle存储过程...
  10. 移动语音引擎相关开发笔记
  11. Linux查看JDK版本和安装位置
  12. matlab机器学习预测股价+python爬虫
  13. js获取url一级域名的方法
  14. 搬运小视频为什么要修改MD5值?什么是MD5?
  15. 旷视科技完成4.6亿美元C轮融资,再破AI融资记录 | 聚焦
  16. java是怎么分配内存和释放内存的-详解
  17. python 绝对值最小值的 正数_找出有序数组中绝对值最小的数
  18. 通过100个单词掌握英语语法(二十二)give
  19. RMB小写转换成大写
  20. (附源码)spring boot大学生综合素质测评系统 毕业设计162308

热门文章

  1. Linux从入门到精通——自动安装脚本
  2. [转] 在Mac上搭建React Native开发环境
  3. Request对象 --web浏览器向web服务端的请求
  4. Linux内核实验作业四
  5. (笔记) (ARM) QQ2440 开发板改为 GT2440 (Linux) (开发板)
  6. JS中setTimeout()的使用方法具体解释
  7. 桌面打开图片时很慢,显示正在生成预览好几秒的解决办法
  8. 初学Python常见异常错误,总有一处你会遇到!
  9. 从前端角度看网页渲染慢的原理及解决方案
  10. Echarts 解决饼图文字过长重叠的问题