码迷,mamicode.com
首页 > 编程语言 > 详细

javaJVM-类加载机制

时间:2020-06-17 23:46:50      阅读:99      评论:0      收藏:0      [点我收藏+]

标签:读取   验证   解释   右键   它的   http   name   概念   编译器   

我们知道,我们写的java文件是不能直接运行的,我们可以在IDEA中右键文件名点击运行,或者可以放到服务器上作为服务运行,这中间其实掺杂了一系列的复杂处理过程。

这篇文章,我们只讨论我们的代码在运行之前的一个环节,叫做类的加载。按照我写文章的常规惯例,先给出这篇文章的大致结构;

一、什么是类的加载

在介绍类的加载机制之前,先来看看,类的加载机制在整个java程序运行期间处于一个什么环节,下面使用一张图来表示:

 

技术图片

 

 从上图可以看,java文件通过编译器变成了.class文件,接下来类加载器又将这些.class文件加载到JVM中。其中类装载器的作用其实就是类的加载。今天我们要讨论的就是这个环节。有了这个印象之后我们再来看类的加载的概念:

 

二、类加载的过程

类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。它们的顺序如下图所示:

技术图片

分别一一解释各阶段做的事情

1、加载:

  类加载指的是将类的class文件读入内存,并为之创建一个java.lang.Class对象,作为方法区这个类的数据访问的入口

也就是说,当程序中使用任何类时,系统都会为之建立一个java.lang.Class对象。具体包括以下三个部分:

(1)通过类的全名产生对应类的二进制数据流。(根据early load原理,如果没找到对应的类文件,只有在类实际使用时才会抛出错误)

(2)分析并将这些二进制数据流转换为方法区方法区特定的数据结构

(3)创建对应类的java.lang.Class对象,作为方法区的入口(有了对应的Class对象,并不意味着这个类已经完成了加载链接)

 

通过使用不同的类加载器,可以从不同来源加载类的二进制数据,通常有如下几种来源:

(1)从本地文件系统加载class文件,这是绝大部分程序的加载方式

(2)从jar包中加载class文件,这种方式也很常见,例如jdbc编程时用到的数据库驱动类就是放在jar包中,jvm可以从jar文件中直接加载该class文件

(3)通过网络加载class文件

(4)把一个Java源文件动态编译、并执行加载

2、链接:

    链接指的是将Java类的二进制文件合并到jvm的运行状态之中的过程。在链接之前,这个类必须被成功加载。

类的链接包括验证、准备、解析这三步。具体描述如下:

2.1  验证:

    验证是用来确保Java类的二进制表示在结构上是否完全正确(如文件格式、语法语义等)。如果验证过程出错的话,会抛出java.lang.VertifyError错误。

主要验证以下内容:

  • 文件格式验证
  • 元数据验证:语义验证
  • 字节码验证

2.2  准备:

  准备过程则是创建Java类中的静态域(static修饰的内容),并将这些域的值设置为默认值,同时在方法区中分配内存空间。准备过程并不会执行代码。

注意这里是做默认初始化,不是做显式初始化。例如:

public static int value = 12;

上面的代码中,在准备阶段,会给value的值设置为0(默认初始化)。在后面的初始化阶段才会给value的值设置为12(显式初始化

 

2.3  解析:

  解析的过程就是确保这些被引用的类能被正确的找到(将符号引用替换为直接引用)。解析的过程可能会导致其它的Java类被加载。

符号引用:

    以一组符号来描述所引用的目标,可以是任何形式的字面量,只要是能无歧义的定位到目标就好,就好比在班级中,老师可以用张三来代表你,也可以用你的学号来代表你,但无论任何方式这些都只是一个代号(符号),这个代号指向你(符号引用)。

直接引用:

    直接引用是可以指向目标的指针、相对偏移量或者是一个能直接或间接定位到目标的句柄。和虚拟机实现的内存有关,不同的虚拟机直接引用一般不同。解析动作主要针对类或接口、字段、类方法、接口方法、方法类型、方法句柄和调用点限定符7类符号引用进行。

 

3、初始化:

  初始化阶段是类加载过程的最后一步。到了初始化阶段,才真正执行类中定义的Java程序代码(或者说是字节码)。

在以下几种情况中,会执行初始化过程:

(1)创建类的实例

(2)访问类或接口的静态变量(读取或者设置静态变量)

(3)调用类的静态方法

(4)反射(Class.forName(packagename.className))

(5)初始化某个类的子类,则其父类也会被初始化

(6)java虚拟机启动时被标明为启动类的类(main方法所在类,JVM会先初始化这个类)

 

二 类加载器

 

三 栈帧

 

四 解析和分派

 

五  Class类文件结构解析

 

javaJVM-类加载机制

标签:读取   验证   解释   右键   它的   http   name   概念   编译器   

原文地址:https://www.cnblogs.com/hup666/p/13155177.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!