理解JVM之类加载机制
类完整的生命周期包括加载,验证,准备,解析,初始化,使用,卸载,七个阶段.其中验证,准备,解析统称为连接,类的卸载在前面的关于垃圾回收的博文中已经介绍.
加载,验证,准备,初始化,卸载这五个阶段的顺序是确定的,类的加载必须按照这种顺序按部就班的来,而解析阶段不一定,它可以在初始化阶段之后开始,这是为了支持java的运行时动态绑定.值得注意的是,上述的五个阶段只是按部就班的"开始",并不是按部就班的"进行"或者"完成",因为这些阶段通常是互相交叉混合进行的,通常会在一个阶段执行的过程调用,激活另一个阶段.
在java虚拟机规范中并没有进行强制约束什么时候加载类,这是交给虚拟机具体实现自由把握,但是对于初始化阶段,虚拟机规范有严格规定:
1.使用new实例化对象或者读取,设置一个类的静态字段(被final或者已在编译器吧结果放入常量池的静态字段除外)的时候以及调用一个类的静态方法的时候.
2.使用反射调用的时候,如果类没初始化,需要进行初始化
3,当初始化一个类的时候,父类没有初始化,则需要先初始化父类
4.虚拟机启动时,用户需要制定一个执行类(包含main方法的那个类),虚拟机会先初始化这个主类.
5.使用动态语言支持时,如果一个java.lang.MethodHandle实例最后解析结果REF_getStatic,REF_putStatic,REF_invokeStatic的方法句柄,并且这个句柄锁对应的类没有初始化,则初始化这个类.
下面具体介绍类加载的过程.
1.加载
加载阶段,虚拟机需要完成3件事情:
1) 通过一个类的全限定名来获取定义此类的二进制字节流
2) 将这个字节流锁代表的静态存储结构转化为方法区的运行时数据结构
3) 在内存中生成带包这个类的Class对象,作为方法区这个类的各种数据访问入口.
对于数组类而言,情况不同,数组类本身不通过类加载器创建,它是由java虚拟机直接创建.数组类的创建过程遵循以下规则:
1) 如果数组的组件类型(指数组去掉一个维度的类型)是引用类,那就采取上述的方法来加载这个组件类型,数组C将在加载该组件类型的类加载器的类名空间上被标识
2) 如果数组的组件类型不是引用类型(例如int[]),虚拟机会将数组标记为与引导类加载器关联
3) 数组类的可见性与他的组件类型的可见性一直,如果组件类型不是引用类型,那数组类的可见性将默认为public.
加载完成后,外部二进制字节流就按照虚拟机需要的格式存储在方法区中,然后实例化一个Class类的对象作为程序访问方法区中的这些类型数据的外部接口.
2.验证
验证是连接的第一步,这一阶段为了确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全.验证分为四个阶段:文件格式验证,元数据验证,字节码验证,符号引用验证
1) 文件格式验证是验证字节流是否符合Class文件格式的规范,并且能够被当前版本的处理机处理.
2) 元数据验证是对字节码描述的信息进行语义分析,以保证其描述的信息符合java语言规范的要求.
3) 字节码验证是只能怪过验证过程最复杂的阶段,主要是通过数流和控制流分析,确定程序语义是合法的,符合逻辑的.这个阶段对类的方法体进行校验分析,保证被校验类的方法在运行时不会出现危害虚拟机安全的事件.
4) 符号引用验证发生在虚拟机将符号引用转化为直接引用的时候.这个动作是在解析阶段发生.
3.准备
这个阶段是正式为类变量分配内存并设置类变量初始值的阶段,这些变量锁使用的内存都在方法区中分配.值得注意的是这里进行分配内存的仅包括类变量(被static修饰的变量),不包括实例变量,其次这里设置初始值是将值设为零值,例如一个整型类变量设置的零值是0,而不是代码中写出来的值.将代码写出来的值赋值给这个变量是初始化阶段做的事情
4.解析
解析阶段是虚拟机将常量池的符号引用替换为直接引用的过程.解析包括类或接口的解析,字段解析,类方法解析,接口方法解析
5.初始化
初始化是类加载的最后一步,在准备阶段,变量已经赋过一次系统要求的初始值,而在初始化阶段,则根据程序员通过程序制定的主观计划去初始化类变量和其他资源,或者换一种说法:初始化阶段是执行类构造器<clinit>()方法的过程.
<cliinit>()方法时由编译器自动收集所有类变量的赋值动作和静态语句快中的语句合并产生的,收集的顺序是由语句在源文件中出现的顺序决定的,静态语句块只能访问到定义域在静态语句块之前的变量,后面的变量只能赋值,不能访问.
<cliinit>()方法还有许多规定,请自行查找相关资料
6.类与类加载器
类加载器虽然只用于实现类加载动作,但是在java程序中的还有其他作用.对于任意一个类加载器,都有一个独立的类名空间,而被这个类加载器加载出来的类,其类名会被标记上类加载器的类名空间,则两个特性决定了一个类在虚拟机中的唯一性.也就是说我们要比较两个类是否相等,前提是要这两个类是同一个类加载器加载出来的.否则就算是同一个class文件加载出来的这两个的也是不相等的.因为instanceof这个关键字会将两个类判定为不是同一个类,
7.双亲委派模型
这个模型的工作过程是:如果一个类加载器收到了类加载请求,它首先不会自己尝试加载这个类,而是吧这个请求委派给父类加载器去完成.因此所有的加载请求最终都会送到顶层的启动类加载器,只有父类反馈无法完成类加载让子加载器才会尝试加载.这个模型使java的类不会因为类加载器不同而产生不同的相同类.
理解JVM之类加载机制的更多相关文章
- 深入理解JVM(3)——类加载机制
1.类加载时机 类的整个生命周期包括了:加载( Loading ).验证( Verification ).准备( Preparation ).解析( Resolution ).初始化( Initial ...
- 深入理解JVM - 虚拟机类加载机制 - 第七章
类加载的时机类从被加载到虚拟机内存开始,到卸载出内存为止,它的整个生命周期包括了:加载/验证/准备/解析/初始化/使用/卸载七个阶段.其中验证/准备和解析统称为连接(Linking). 加载.验证.准 ...
- 深入理解JVM的类加载
前言: 前面又说到Java程序实际上是将.class文件放入JVM中运行.虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,转换,解析和初始化,最终形成可以被虚拟机直接使用的Java类 ...
- 【深入理解JVM】类加载器与双亲委派模型 (转)
出处: [深入理解JVM]类加载器与双亲委派模型 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因.在类加载的第一阶段“加载”过程中,需要通过 ...
- 大白话谈JVM的类加载机制
前言 我们很多小伙伴平时都是做JAVA开发的,那么作为一名合格的工程师,你是否有仔细的思考过JVM的运行原理呢. 如果懂得了JVM的运行原理和内存模型,像是一些JVM调优.垃圾回收机制等等的问题我们才 ...
- 一文教你读懂JVM的类加载机制
Java运行程序又被称为WORA(Write Once Run Anywhere,在任何地方运行只需写入一次),意味着我们程序员小哥哥可以在任何一个系统上开发Java程序,但是却可以在所有系统上畅通运 ...
- JVM内存结构 JVM的类加载机制
JVM内存结构: 1.java虚拟机栈:存放的是对象的引用(指针)和局部变量 2.程序计数器:每个线程都有一个程序计数器,跟踪代码运行到哪个位置了 3.堆:对象.数组 4.方法区:字节流(字节码文件) ...
- JVM之类加载机制
JVM之类加载机制 JVM类加载机制分为五个部分:加载,验证,准备,解析,初始化,下面我们就分别来看一下这五个过程. 类加载五部分 加载 加载是类加载过程中的一个阶段,这个阶段会在内存中生成一个代表这 ...
- JVM的类加载机制全面解析
什么是类加载机制 JVM把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被JVM直接使用的Java类型,这就是JVM的类加载机制. 如果你对Class文件的结 ...
随机推荐
- Labelme数据转mask_rcnn数据格式
labelme数据转mask_rcnn数据格式 # coding: utf-8 import argparse import json import os import os.path as osp ...
- 线程或进程绑定到特定的cpu
常用的宏定义有: 1) 对cpu集进行初始化, 将其设置为空集 void CPU_ZERO(cpu_set_t *set); 2) 将指定的cpu加入到cpu集中 void CPU_SET(int c ...
- Egret的第三方库制作,以及在大型项目中的应用
目录: 一 创建第三方库 二 TypeScript库 三 JavaScript库 四 第三方库制作在大型RPG中的实际应用 参考: 第三方库的使用方法 目标: 本文目的是将现有游戏的框架制作成第三方库 ...
- Django之密码加密
通过django自带的类库,来加密解密很方便,下面来简单介绍下: 导入包: from django.contrib.auth.hashers import make_password, check_p ...
- C#DbHelperOleDb,Access数据库帮助类 (转)
/// <summary>/// 编 码 人:苏飞/// 联系方式:361983679 /// 更新网站:[url=http://www.sufeinet.com/thread-655- ...
- 【NANO】引脚说明
http://bbs.eeworld.com.cn/forum.php?mod=viewthread&tid=489650&page=1
- [转载] HashMap的工作原理-hashcode和equals的区别
目录 前言 为什么需要使用Hashcode,可以从Java集合的常用需求来描述: 更深入的介绍 先来些简单的问题 HashMap的0.75负载因子 总结 我在网上看到的这篇文章,介绍的很不错,但是我看 ...
- 安卓微信overflow-x overflow-y引发的bug
今天xgo文章图片页上线用微信扫页面发现一个bug,页面可以双击放大缩小. 找了半天原因,发现是图片描述设置了overflow-y引发的bug. 建议在微信场景里满屏显示不能滚动的页面里慎用overf ...
- 服务发现框架选型,Consul还是Zookeeper还是etcd
背景 本文并不介绍服务发现的基本原理.除了一致性算法之外,其他并没有太多高深的算法,网上的资料很容易让大家明白上面是服务发现. 想直接查看结论的同学,请直接跳到文末. 目前,市面上有非常多的服务发现工 ...
- sql 查找最晚入职员工
题目描述 查找最晚入职员工的所有信息CREATE TABLE `employees` (`emp_no` int(11) NOT NULL,`birth_date` date NOT NULL,`fi ...