文档章节

虚拟机类加载的机制

laohng1995
 laohng1995
发布于 2017/02/26 22:43
字数 1603
阅读 9
收藏 0
点赞 0
评论 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
粉丝 10
博文 32
码字总数 27788
作品 0
南岸
程序员
Java基础巩固笔记(3)-类加载器

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

卟想苌亣 ⋅ 2017/12/04 ⋅ 0

Java程序员从笨鸟到菜鸟之(九十八)深入java虚拟机(七)深入源码看java类加载器ClassLoader

欢迎阅读本专题的其他博客: 深入java虚拟机(一)——java虚拟机底层结构详解 深入java虚拟机(二)——类的生命周期(上)类的加载和连接 深入java虚拟机(三)——类的生命周期(下)类的初...

长平狐 ⋅ 2012/11/12 ⋅ 0

Java中的类加载器

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

java大哥 ⋅ 2017/11/23 ⋅ 0

加载器和双亲委派

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

yan5845hao ⋅ 2016/05/27 ⋅ 0

关于Java类加载双亲委派机制的思考(附一道面试题)

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

tantexian ⋅ 2016/03/22 ⋅ 0

Android 简单热修复(上)——Java类加载器

作为阳历新年的第一篇文章,本想把之前总结的用到实践中,简单写了个钟表,写着写着感觉索然无味(/ □ )。写完后,百无聊赖之际,随便翻看了些技术文章。让我眼前为之一亮的有两个: Androi...

nick_young ⋅ 01/05 ⋅ 0

Java类加载

本篇笔记的目标是理解类加载器的架构,学会实现类加载器并理解热替换的底层原理。 什么是类加载 类从被加载到虚拟机内存中开始,到卸载出内存为止,包括了以下几个生命周期: image.png 什么...

德彪 ⋅ 2017/11/27 ⋅ 0

JAVA 虚拟机类加载机制和字节码执行引擎

引言 我们知道java代码编译后生成的是字节码,那虚拟机是如何加载这些class字节码文件的呢?加载之后又是如何进行方法调用的呢? 一 类文件结构 无关性基石 java有一个口号叫做一次编写,到处...

jiangmitiao ⋅ 2015/07/26 ⋅ 17

让类活起来——漫谈JVM类加载机制

所谓类加载机制,就是虚拟机把描述类的数据从Class文件加载到内存中,并对其进行校验,转换,分析以及初始化,并最终形成虚拟机可以被使用java类型的过程。 Java作为解释型语言,支持动态加载...

登高且赋 ⋅ 01/09 ⋅ 0

反射一些理解

java反射详解 自己的一些理解: 反射也可以理解为动态调用写了一个.java文件,编译后为字节码文件,虚拟机加载了这个字节码文件也就是加载到内存中,就能执行一些指令。在这个类中 当我需要调...

notyBoy ⋅ 2014/02/28 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Sqoop

1.Sqoop: 《=》 SQL to Hadoop 背景 1)场景:数据在RDBMS中,我们如何使用Hive或者Hadoop来进行数据分析呢? 1) RDBMS ==> Hadoop(广义) 2) Hadoop ==> RDBMS 2)原来可以通过MapReduce I...

GordonNemo ⋅ 50分钟前 ⋅ 0

全量构建和增量构建的区别

1.全量构建每次更新时都需要更新整个数据集,增量构建只对需要更新的时间范围进行更新,所以计算量会较小。 2.全量构建查询时不需要合并不同Segment,增量构建查询时需要合并不同Segment的结...

无精疯 ⋅ 今天 ⋅ 0

如何将S/4HANA系统存储的图片文件用Java程序保存到本地

我在S/4HANA的事务码MM02里为Material维护图片文件作为附件: 通过如下简单的ABAP代码即可将图片文件的二进制内容读取出来: REPORT zgos_api.DATA ls_appl_object TYPE gos_s_obj.DA...

JerryWang_SAP ⋅ 今天 ⋅ 0

云计算的选择悖论如何对待?

导读 人们都希望在工作和生活中有所选择。但心理学家的调查研究表明,在多种选项中进行选择并不一定会使人们更快乐,甚至不会产生更好的决策。心理学家Barry Schwartz称之为“选择悖论”。云...

问题终结者 ⋅ 今天 ⋅ 0

637. Average of Levels in Binary Tree - LeetCode

Question 637. Average of Levels in Binary Tree Solution 思路:定义一个map,层数作为key,value保存每层的元素个数和所有元素的和,遍历这个树,把map里面填值,遍历结束后,再遍历这个map,把每...

yysue ⋅ 今天 ⋅ 0

IDEA配置和使用

版本控制 svn IDEA版本控制工具不能使用 VCS-->Enable Version Control Integration File-->Settings-->Plugins 搜索Subversion,勾选SVN和Git插件 删除.idea文件夹重新生成项目 安装SVN客户......

bithup ⋅ 今天 ⋅ 0

PE格式第三讲扩展,VA,RVA,FA的概念

作者:IBinary 出处:http://www.cnblogs.com/iBinary/ 版权所有,欢迎保留原文链接进行转载:) 一丶VA概念 VA (virtual Address) 虚拟地址的意思 ,比如随便打开一个PE,找下它的虚拟地址 这边...

simpower ⋅ 今天 ⋅ 0

180623-SpringBoot之logback配置文件

SpringBoot配置logback 项目的日志配置属于比较常见的case了,之前接触和使用的都是Spring结合xml的方式,引入几个依赖,然后写个 logback.xml 配置文件即可,那么在SpringBoot中可以怎么做?...

小灰灰Blog ⋅ 今天 ⋅ 0

冒泡排序

原理:比较两个相邻的元素,将值大的元素交换至右端。 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第...

人觉非常君 ⋅ 今天 ⋅ 0

Vagrant setup

安装软件 brew cask install virtualboxbrew cask install vagrant 创建project mkdir -p mst/vmcd mst/vmvagrant init hashicorp/precise64vagrant up hashicorp/precise64是一个box......

遥借东风 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部