在对类的实例化之前。JVM 一般会先进行初始化

主要经过如下几个阶段:

  1.加载                      

类加载的第一阶段,类加载时机有两个:

1.预加载:当虚拟机启动时,会预加载HOME/lib下的rt.jar里的.class文件

里面包括java.lang.*、java.util.*、java.io.*、

还有加载当前启动类并调用main方法

2.运行时加载:

首先会去内存中找.class文件有没被加载,没有的话就会按照类的全限定名进行加载

加载(load)阶段.

1.1获取类的二进制流文件

1.2将类的信息、常量、静态变量存到方法区(的运行时常量池)中,

1.3在内存中生成该.class文件的java.lang.class对象,作为方法区内这个类的数据访问入口.(HotSpot 比较特殊,他把class对象存到方法区中)

  2.验证                      

确保.class文件中的字节流信息能够被正确的加载并不会危害到虚拟机的安全

  3.准备                      

类的静态变量分配内存并赋初始值.这时候分配内存的仅仅是静态变量,实例变量会随着类的实例化一起存储在堆内存中

int声明的默认为0等.被final修饰变量直接赋值

例:public static int a=3;

public static final int b=3;

在准备阶段a的值是0,而把a赋值为3的putstatic指令是在程序编译后存放于类构造器<clinit>()方法之中的,所以把a赋值为3的动作将在初始化阶段才会执行,b就直接赋值为3

  4.解析                      

将符号的引用变为直接引用

这个涉及到编译原理,符号的引用一般有以下三个常量:

1.类的全限定名

2.方法的名称和描述符

3.字段的名称和描述符

直接引用可以是直接指向目标的指针、相对偏移量或是一个能间接指向目标的句柄

  5.初始化                                                          

真正执行java字节码的过程..初始化过程是执行一个类初始化构造器<client>init()的过程

说白了就是为被static修饰的变量赋于程序指定的值并执行静态代码块

类初始化时机:只有当对类的主动使用的时候才会导致类的初始化,类的主动使用包括以下六种:

– 创建类的实例,也就是new的方式

– 访问某个类或接口的静态变量,或者对该静态变量赋值

– 调用类的静态方法

– 反射(如Class.forName(“com.shengsiyuan.Test”))

– 初始化某个类的子类,则其父类也会被初始化

– Java虚拟机启动时被标明为启动类的类(Java Test),直接使用java.exe命令来运行某个主类

参考链接:http://www.cnblogs.com/xrq730/p/4844915.html

类加载器                                                 

类与类加载器

虚拟机设计团队把类加载阶段的"通过一个类的全限定名来获取此类的二进制字节流"这个动作放到Java虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类。

实现这个动作的代码模块称为"类加载器"。类加载器虽然只用于实现类的加载动作,但它在Java程序中起到的作用却远远不限定于类加载阶段。

对于任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在Java虚拟机中的唯一性,每一个类加载器,都拥有一个独立的类名称空间。

这句话表达地再简单一点就是:比较两个类是否"相等",只有在这两个类是由同一个类加载器加载的前提下才有意义,否则即使这两个类来源于同一个.class文件,被同一个虚拟机加载,只要加载它们的类加载器不同,这两个类必定不相等。

上面说的"相等",包括代表类的.class对象的equals()方法、isAssignableFrom()方法、isInstance()方法的返回结果,也包括使用instanceof关键字做对象所属关系判定等情况。

双亲委派模型

最后讲一下双亲委派模型,其实上面的类加载器模型图就是一个双亲委派模式的图,这里把它再讲清楚一点。

双亲委派模型是在JDK1.2期间被引入的,其工作过程可以分为两步:

1、如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此。

2、只有当父加载器反馈自己无法完成这这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载

所以,其实所有的加载请求最终都应该传送到顶层的启动类加载器中。双亲委派模型对于Java程序的稳定运作很重要,因为Java类随着它的加载器一起具备了一种带有优先级的层次关系。

例如java.lang.Object,存放于rt.jar中,无论哪一个类加载器要去加载这个类,最终都是由Bootstrap ClassLoader去加载,因此Object类在程序的各种类加载器环境中都是一个类。

相反,如果没有双亲委派模型,由各个类自己去加载的话,如果用户自己编写了一个java.lang.Object,并放在CLASSPATH下,那系统中将会出现多个不同的Object类,Java体系中最基础的行为也将无法保证,应用程序也将会变得一片混乱。

JVM 类的加载机制的更多相关文章

  1. Jvm类的加载机制

    1.概述 虚拟机加载Class文件(二进制字节流)到内存,并对数据进行校验.转换解析和初始化,最终形成可被虚拟机直接使用的Java类型,这一系列过程就是类的加载机制. 2.类的加载时机 类从被虚拟机加 ...

  2. java架构之路-(JVM优化与原理)JVM类的加载机制

    话不多说,先上图. ***.class文件执行大概就是这样来走的.我们都知道我们的java文件经过编译以后会生成对应的class文件.先经过类装载子系统,然后塞进运行时内存模型的元空间,开始执行方法, ...

  3. jvm系列(一):java类的加载机制

    java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装 ...

  4. jvm系列 (五) ---类的加载机制

    类的加载机制 目录 jvm系列(一):jvm内存区域与溢出 jvm系列(二):垃圾收集器与内存分配策略 jvm系列(三):锁的优化 jvm系列 (四) ---强.软.弱.虚引用 我的博客目录 什么是类 ...

  5. JVM(1):Java 类的加载机制

    原文出处: 纯洁的微笑 java类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang. ...

  6. 深入java虚拟机学习 -- 类的加载机制

    当看到"类的加载机制",肯定很多人都在想我平时也不接触啊,工作中无非就是写代码,不会了可以百度,至于类,jvm是怎么加载的我一点也不需要关心.在我刚开始工作的时候也觉得这些底层的内 ...

  7. JVM-01:类的加载机制

    本文从 纯洁的微笑的博客 转载 原地址:http://www.ityouknow.com/jvm.html 类的加载机制 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内 ...

  8. 24.类的加载机制和反射.md

    目录 1类的加载连接和初始化 1.1类的加载过程 1.2类的加载器 1.2.1类的加载机制 1类的加载连接和初始化 1.1类的加载过程 类的加载过程简单为分为三步:加载->连接->初始化 ...

  9. 深入java虚拟机学习 -- 类的加载机制(续)

    昨晚写 深入java虚拟机学习 -- 类的加载机制 都到1点半了,由于第二天还要工作,没有将上篇文章中的demo讲解写出来,今天抽时间补上昨晚的例子讲解. 这里我先把昨天的两份代码贴过来,重新看下: ...

随机推荐

  1. 8年开发老司机告诉你啥是java开发?如何学?学习什么内容?

    什么是Java? 我从Java的官网上抄下来下面这段话:97% 的企业桌面运行 Java美国有 89% 的桌面(或计算机)运行 Java全球有 900 万 Java 开发人员开发人员的头号选择排名第一 ...

  2. Hyperledger Fabric私有数据

    官方文档:点这里 1简介 在同一个通道中,允许某一组织在对同一通道内其他组织保持部分的数据私有.也就是说有一部分被标识为私有的数据只能具有权限的组织查看和操作,而其余组织不具备查看和操作私有数据的权限 ...

  3. Flutter - flutter desktop embedding / flutter 桌面支持

    2019年5月9日,随着谷歌在IO19宣布Flutter支持Web平台,就标志着Flutter已经全面支持所有平台(移动.网页.桌面.嵌入式). 现编一个跨平台小段子: 微软Xarmarin:喵喵喵? ...

  4. 记录开发基于百度地图API实现在地图上绘制轨迹并拾取轨迹对应经纬度的工具说明

    前言: 最近一直在做数据可视化方面的工作,其中平面可视化没什么难度,毕竟已经有很多成熟的可供使用的框架,比如百度的echart.js,highcharts.js等.还有就是3D可视化了,整体来说难度也 ...

  5. js 实现ReplaceAll 的方法

    JS  字符串有replace() 方法.但这个方法只会对匹配到的第一个字串替换. 如下例: <HTML> <HEAD> <TITLE> New Document ...

  6. 关于华为模拟器eNSP-防火墙USG6000V怎么重装镜像

    一.首先关闭eNSP软件 二.打开Oracle VM VirtualBox 三.单击VirtualBox “管理 - 虚拟介质管理”,将vfw_usg.vdi下面的子链接释放然后删除 四.最后回到主界 ...

  7. tornado框架中redis使用

    一.安装依赖 pip3 install tornado-redis 二.导入模块 import tornadoredis 三.创建redis对象 import tornadoredis CONNECT ...

  8. 学习DDD的初步尝试,从最基础的开始,业务介绍,划分限界上下文 ,建立模型

    Conference业务简介 Conference是这样一个系统,它提供了一个在线创建会议以及预订会议座位的平台.这个系统的用户有两类: 1:客户,可以创建和管理会议. 2:会议座位预定者,可以预订会 ...

  9. 内存取证工具-volatility、foremost

    内存取证 1. 内存取证工具volatility 猜测dump文件的profile值 root@kali:~/CTF# volatility -f mem.vmem imageinfo Volatil ...

  10. How to use special characters in XML?

    https://dvteclipse.com/documentation/svlinter/How_to_use_special_characters_in_XML.3F.html Because X ...