加载是类加载的第一步。

一、加载

a)加载的过程

  1)通过一个类的全限定名获取这个类的二进制字节流,也就是class文件

  2)将二进制字节流的存储结构转换为特定的数据结构,存储在方法区

  3)在内存中创建一个Java.lang.Class的对象,接下来在程序运行的过程中所有对这个类的访问都是通过这个Class类型的对象进行访问的。

b)从那里加载二进制字节流

  1) 一般的二进制字节流都是通过已经编译好的本地class文件中进行加载

  2) 从压缩文件中进行加载

  3)从网络中进行加载

  4)从数据库中进行加载

  5) 通过其他文件动态生成

c)普通类的加载和数组类加载过程的区别

数组也是一种数据类型,成为数组类型。String[] str = new String[10];这是一个数组类型,只不过是该数组的数据元素是String类型,在程序运行过程中当遇到new需要创建一个数组的时候,JVM会首先创建一个数组类,然后再由类加载器创建数组中的元素类;但是普通类的创建过程就是直接由类加载器创建。

d) 加载过程的注意点

  1)  JVM并没有给出类在方法区存放的数据结构

  2) JVM并没有给出Class对象的存放位置

  3)  加载阶段和连接阶段是交叉进行的,类加载过程中每个步骤的开始顺序有要求限制,但是并没有规定每个步骤的结束顺序

二、验证

  a)验证的目的:保证二进制字节流中的二进制信息符合JVM的规范,不会出现安全问题。

  b)为什么需要验证:

Java是一门安全语言,他能确保程序员不会访问数组之外的内存、不会把一个对象转换成任意类型、能避免代码跳转到一个不存在的地方,如果出现这样的情况,编译过程就会报错,这就是说Java语言的安全性是通过编译器实现的。

我们知道编译器和虚拟机是两个相互独立的部分,虚拟机只认二进制字节码,但是它不关心二进制字节码的来源,如果是Java编译器生成的二进制字节码,那么就会相对的安全,但是还能通过其他的途径获取到二进制字节码,这样的二进制字节码是没办法保证符合JVM规范的,为了防止二进制字节流中出现安全问题,因此需要验证。

  c) 验证的过程:

    1)文件格式的验证

    2)元数据的验证

    3)字节码的验证

    4) 符号引用的验证

三、准备:

  a) 为已经在方法区中的类的静态成员变量分配内存

  b)为静态成员变量设置初始值(默认初始化)

四、解析:是虚拟机将常量池中的符号引用变为直接引用的过程

五、 初始化:就是执行类构造器Clinit()方法的过程。Clinit()方法是编译器自动产生的,收集类中静态代码块中的类成员变量赋值语句和类的静态成员变量赋值语句。在准备阶段,类的静态成员变量已经被默认初始化,但是在初始化阶段需要进行显示的初始化。

六、初始化过程中需要注意的点:

  a)clinit()方法对类中的静态成员变量赋值的顺序是根据代码中成员变量出现的顺序进行赋值的;

  b)静态代码块能够访问在静态代码块之前出现的类的静态成员变量,在其后的静态成员变量不能被访问

  c)静态代码块能够为出现在其后的静态成员变量赋值

  d)构造函数init()需要显示的调用父类的构造器,但是类的clinit()方法不用调用父类的这个方法,因为虚拟机会保证在执行这个类的clinit()方法之前已经执行了父类的这个方法。

  e)如果在接口/类中没有静态代码块也没有类的静态成员变量的话,那么编译器就不会生成clinit()方法

  f)接口中只会出现静态成员变量,不会出现静态代码块,如果出现静态成员变量的话,编译器就会自动生成一个clinit()方法

  g)接口在执行clinit()方法的时候不会确保其父接口的clinit()方法已经被执行,只有当父接口中的静态成员变量被执行到的时候才会执行父接口的clinit()方法。

  h) 虚拟机会给clinit()方法上锁,当多个线程同时执行某一个类的clinit()方法的时候,只能有一个线程能够正常执行,其他的线程会被阻塞,并且只要这个类的clinit()方法已经被执行过之后,其他的线程就不能在执行,这样也就保证了在同一个类加载器下一个类只能被初始化一次。

深入理解JVM(9)——类加载的过程的更多相关文章

  1. 【深入理解JVM】类加载器与双亲委派模型 (转)

    出处: [深入理解JVM]类加载器与双亲委派模型 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因.在类加载的第一阶段“加载”过程中,需要通过 ...

  2. 深入理解JVM之类加载

    ---title: [学习]深入理解JVM之类加载.mddate: 2019-10-20 22:20:06tags: JVM 类加载--- Java类的加载,连接,初始化都是在程序运行期间执行的 ## ...

  3. 深入理解JVM的类加载

    前言: 前面又说到Java程序实际上是将.class文件放入JVM中运行.虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,转换,解析和初始化,最终形成可以被虚拟机直接使用的Java类 ...

  4. JVM实战---类加载的过程

    任何程序都需要加载到内存才能与CPU进行交流 同理, 字节码.class文件同样需要加载到内存中,才可以实例化类 ClassLoader的使命就是提前加载.class 类文件到内存中 在加载类时,使用 ...

  5. 理解JVM之类加载机制

    类完整的生命周期包括加载,验证,准备,解析,初始化,使用,卸载,七个阶段.其中验证,准备,解析统称为连接,类的卸载在前面的关于垃圾回收的博文中已经介绍. 加载,验证,准备,初始化,卸载这五个阶段的顺序 ...

  6. 【深入理解JVM】类加载器与双亲委派模型

    原文链接:http://blog.csdn.net/u011080472/article/details/51332866,http://www.cnblogs.com/lanxuezaipiao/p ...

  7. 深入理解JVM(3)——类加载机制

    1.类加载时机 类的整个生命周期包括了:加载( Loading ).验证( Verification ).准备( Preparation ).解析( Resolution ).初始化( Initial ...

  8. 深入理解JVM一类加载器原理

    我们知道我们编写的java代码,会经过编译器编译成字节码文件(class文件),再把字节码文件装载到JVM中,映射到各个内存区域中,我们的程序就可以在内存中运行了.那么字节码文件是怎样装载到JVM中的 ...

  9. 深入理解JVM - 虚拟机类加载机制 - 第七章

    类加载的时机类从被加载到虚拟机内存开始,到卸载出内存为止,它的整个生命周期包括了:加载/验证/准备/解析/初始化/使用/卸载七个阶段.其中验证/准备和解析统称为连接(Linking). 加载.验证.准 ...

  10. 深入理解JVM,类加载器

    虚拟机设计团队把类加载阶段中的“通过一个类的全限定名来获取描述此类的二进制字节流(即字节码)”这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这个动作的代码模块称 ...

随机推荐

  1. jQuery 核心 - noConflict() 方法[避免冲突的方法]

    定义和用法 noConflict() 方法让渡变量 $ 的 jQuery 控制权. 语法 jQuery.noConflict([removeAll]) 参数描述removeAll布尔值.指示是否允许彻 ...

  2. 解决Python安装模块出错 ImportError: No module named setuptools

    1.下载ez_setup.py文件 下载地址:https://bootstrap.pypa.io/ez_setup.py 百度地址:http://pan.baidu.com/s/1jIgMO9w 2. ...

  3. Refs & DOM

    Refs 提供了一种访问在 render 方法中创建的 DOM 节点或 React 元素的方式. 在典型的 React 数据流中, 属性(props)是父组件与子代交互的唯一方式.要修改子组件,你需要 ...

  4. WebAPI——自动生成帮助文档

    Web Api 自动生成帮助文档   新建Web Api项目之后,会在首页有API的导航菜单,点击即可看到API帮助文档,不过很遗憾,Description 是没有内容的. 怎么办呢? 第一步: 如果 ...

  5. HTML5上传图片预览功能

    HTML5上传图片预览功能 HTML代码如下: <!-- date: 2018-04-27 14:41:35 author: 王召波 descride: HTML5上传图片预览功能 --> ...

  6. Nginx的配置与部署研究,Upstream负载均衡模块

    Nginx 的 HttpUpstreamModule 提供对后端(backend)服务器的简单负载均衡.一个最简单的 upstream 写法如下: upstream backend { server ...

  7. UOJ#23. 【UR #1】跳蚤国王下江南 仙人掌 Tarjan 点双 圆方树 点分治 多项式 FFT

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ23.html 题目传送门 - UOJ#23 题意 给定一个有 n 个节点的仙人掌(可能有重边). 对于所有 ...

  8. Codeforces 1016G Appropriate Team 数论 FWT

    原文链接https://www.cnblogs.com/zhouzhendong/p/CF1016G.html 题目传送门 - CF1016G 题意 给定 $n,x,y$ ,以及一个含有 $n$ 个元 ...

  9. 怎样将一个Long类型的数据转换成字节数组

    直接上代码: //先写进去 long n = 1000000L; ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutpu ...

  10. redis虚拟内存

    对于redis 这样的内存数据库, 内存总是不够用的. 除了可以将数据分割到多个 redis 服务器以外. 另外的能够提高数据库容量的办法就是使用虚拟内存技术把那些不经常访问的数据交换到磁盘上 如果我 ...