文档章节

虚拟机类加载的机制

laohng1995
 laohng1995
发布于 2017/02/26 22:43
字数 1603
阅读 9
收藏 0

 

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

 1.类加载的时机

类加载的生命周期包括:加载,验证,准备,解析,初始化,使用,卸载。

第一个阶段:加载。  

在加载阶段,虚拟机需要完成三个步骤:

第一,通过一个类的全限定名来获取定义此类的二进制流。

第二,将这个字节流所代表的静态存储结构转移为方法区的运行时数据结构

第三,在内存中生成一个代表累的java.lang.Class对象做作文程序访问的入口。

注意:对于数组类型而言,它本身不通过类加载器创建,他是通过虚拟机直接创建,但是仍然和类加载器有着重要的联系,因为数组类型当中元素的创建需要通过类加载器加载。Class对象比较特殊,它他虽然是对象,但是他是存储在方法区

第二个阶段:验证

验证阶段的目的是为了确保Class文件的字节流包含的信息符合当前虚拟机的要求,并且不能伤害虚拟机。

验证的第一阶段为:文件格式的验证,主要用于验证魔术,主次版本号等等

验证的第二阶段:元数据验证:对字节码描述的信息进行语意分析,确保其符合Java虚拟机语言规范。

验证的第三阶段:字节码验证:主要是通过数据流和控制流分析,确定程序合法,合乎逻辑。

验证的第四阶段:符号引用验证。

第三阶段:准备

准备阶段正式为变量分配内存和赋予初始值阶段,这部分的是在方法区内完成。这里所指的变量是指类变量而不是实例变量。例子:

public static int value=123

对于这个赋值而言,准备阶段过后的初始值为0而不是123,因为这个时候Java虚拟机还没有执行任何一个方法,而把value赋值123的putstatic指令实在程序编译后,存放在类构造器<clinit>()方法中,所以在动作执行阶段才能执行赋值。

第四阶段:解析

1.类或接口解析

  1>如果不是一个数组类型,则通过类加载,验证。

  2>如果是数组类型,并且数组的元素是对象类型,也会按照第一点解析

  3>如果前面都没有发生异常,则要进行权限认证

2.字段解析

1)简单的名称进行匹配

2)如果在其中实现接口,会按照继承关系从下向上递归查找各个接口和父接口

3)如果不是Object类的话,将会按照继承关系从下向上递归搜索其父类

4)如果都失败,抛出NoSuchFieldError异常,如果发现没有访问权限,抛出ILLegalAccessError异常

3.类方法解析

4.接口方法解析

第四阶段:初始化

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

<cinit>(()方法使所有的类变量赋值动作和静态语句块顺序所决定的,静态语句块只能访问静态语句块的变量。

<cinit>(()不需父类构造器显示的调用,虚拟机会保证子类的<cinit>()方法执行前父类的<cinit>()方法已经执行。因此第一个被执行的父类是Object的<cinit>()

<cinit>()静态语句块的执行要优先于类变量见得赋值。

<cinit>()对于或者接口与来说不是必须的,如果没有静态代码块和赋值的话,就可以不用<cinit>()。

虚拟机会保证在多线程中<cinit>()被正确的枷锁,同步和执行。

对4种情况必须初始化:

 1.使用new关键字实例化对象的时候,读取或者设置一个类的静态字段的时候,以及调用一个静态类方法的时候。

2.调用reflect包的方法进行反射调用的时候

3.初始化的时候如果发现父类没有初始化的时候要先给父类进行初始化

4.当虚拟机启动的时候需要执行Main方法那个类

 

3种不能触动初始化

1.子类引用父类的静态字段

2.通过数组定义来引用类

3.引用静态的方法

 

介绍一个模型:双亲委派模型

对于Java虚拟机来说,只存在两种不同角度的类加载器:一种是用c++语言实现的,启动类加载器。另一种是用Java语言实现的所有其他的类加载器,独立于虚拟机外,并且继承抽象类ClassLoader。

 

图形:

(1).BootStrap ClassLoader:启动类加载器,负责加载存放在%JAVA_HOME%\lib目录中的,或者通被-Xbootclasspath参数所指定的路径中的,并且被java虚拟机识别的(仅按照文件名识别,如rt.jar,名字不符合的类库,即使放在指定路径中也不会被加载)类库到虚拟机的内存中,启动类加载器无法被java程序直接引用。

(2).Extension ClassLoader:扩展类加载器,由sun.misc.Launcher$ExtClassLoader实现,负责加载%JAVA_HOME%\lib\ext目录中的,或者被java.ext.dirs系统变量所指定的路径中的所有类库,开发者可以直接使用扩展类加载器。

(3).Application ClassLoader:应用程序类加载器,由sun.misc.Launcher$AppClassLoader实现,负责加载用户类路径classpath上所指定的类库,是类加载器ClassLoader中的getSystemClassLoader()方法的返回值,开发者可以直接使用应用程序类加载器,如果程序中没有自定义过类加载器,该加载器就是程序中默认的类加载器。

双亲委派模型的工作过程:如果一个类加载器收到加载请求,他首先不会自己尝试加载这个类,而是把它委派给父类加载去完成。每一个层次都会尝试加载都是如此

© 著作权归作者所有

共有 人打赏支持
laohng1995
粉丝 12
博文 37
码字总数 30590
作品 0
杭州
程序员
私信 提问
Java虚拟机加载类文件大全-精细版

java加载类文件精细版,请仔细看 Java技术提供三种确保安全机制 语言设计特性 (对数组的边界进行检查、类型转换检查、无指针算法) 安全的访问控制机制 代码签名 类加载器 先看一下虚拟机执...

奔跑的蛙牛
08/22
0
0
Java基础巩固笔记(3)-类加载器

Contents java基础巩固笔记(3)-类加载器 默认类加载器 类加载器的委托机制 自定义类加载器的编写原理 参考资料 java类加载器就是在运行时在JVM中动态地加载所需的类,java类加载器基于三个机...

卟想苌亣
2017/12/04
0
0
Java中的类加载器

首先声明,我是因为看了ImportNew网站上的几篇关于类加载器的文章之后,才萌生了写这篇文章的想法。所以在写这篇文章时,参考了该网站上的几篇相关的文章,但是加入了很多自己的理解,绝对不...

java大哥
2017/11/23
0
0
加载器和双亲委派

一道面试题 能不能自己写个类叫java.lang.System? 答案:通常不可以,但可以采取另类方法达到这个需求。 解释:为了不让我们写System类,类加载采用委托机制,这样可以保证爸爸们优先,爸爸...

yan5845hao
2016/05/27
12
0
关于Java类加载双亲委派机制的思考(附一道面试题)

预定义类加载器和双亲委派机制 JVM预定义的三种类型类加载器: 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 <JavaRuntimeHome>/lib下面的类库加载到内存中(比如rt.ja...

tantexian
2016/03/22
33
0

没有更多内容

加载失败,请刷新页面

加载更多

基础编程题目集-7-13 日K蜡烛图

股票价格涨跌趋势,常用蜡烛图技术中的K线图来表示,分为按日的日K线、按周的周K线、按月的月K线等。以日K线为例,每天股票价格从开盘到收盘走完一天,对应一根蜡烛小图,要表示四个价格:开...

niithub
20分钟前
0
0
Jenkins window 下的安装使用

1.下载:https://jenkins.io/download/ 双击安装完毕,将自动打开浏览器: http://localhost:8080 打开对应位置的文件,将初始密钥粘贴至输入框。 第一个是 安装默认的软件;第二个是 自定义...

狼王黄师傅
22分钟前
1
0
深入解析react关于事件绑定this的四种方式

这篇文章主要介绍了详解react关于事件绑定this的四种方式,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下。如有不足之处,欢迎批评指正。 在react组件中,每个方...

前端攻城小牛
31分钟前
1
0
JS正则表达式

url的正则表达式:包括IP,域名(domain),ftp,二级域名,域名中的文件,域名加上端口!用户名等等信息 `function` `IsURL(str_url) {``var` `strRegex =``"^((https|http|ftp|rtsp|mm...

前端小攻略
35分钟前
1
0
shell习题_2

find /root/ceshi1/ -type f -name "*.txt"|xargs -i mv {} {}.bak find /root/ceshi1/ -type f -name "*.txt" -exec mv {} {}.bak \; 1、批量修改文件名: n1=`echo $f|sed '#.bak##'` [ro......

芬野de博客
37分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部