字节码(.class)文件的加载过程
类加载
在Java代码中,类型的加载、连接与初始化过程都是在程序运行期间完成的。
类型可以是Class,Interface, 枚举等。
Java虚拟机与程序的生命周期
在如下几种情况下,Java虚拟机将结束生命周期
1)执行了System.exit() 方法
2)程序正常执行结束
3)程序在执行过程中遇到了异常或者错误而异常终止。
4) 由于操作系统出现错误导致Java虚拟机进程终止。
字节码文件的装载过程: 加载、连接(包括三个步骤: 验证 准备 解析)、初始化
加载:查找并加载类的二进制数据
连接:
验证:确保被加载的类的正确性
准备:为类的静态变量分配内存,并将其初始化为默认值
解析:把类中的符号引用转换为直接引用
符号引用:通俗的讲,是一种间接引用,如一个类中的方法引用了另外一个类,这是一种符号的表述。
直接引用:就是通过指针的方式,直接指向了目标对象内存的位置,这样能一下子找到特定的方法。
初始化: 为类的静态变量赋予正确的初始值
一、类装载的条件
Java程序对类的使用方式分为两种
主动使用
被动使用
所有的Java虚拟机实现必须在每个类或接口被Java程序“首次主动使用”时才初始化他们。
Java虚拟机规定: 一个类或者接口在初次使用时,必须进行初始化。
这里的使用指主动使用,主动使用有以下几种情况:
1) 当创建一个类的实例时。 比如使用new关键字,或者通过反射、克隆、反序列化方式。
2) 当调用类的静态方法时。即当使用了字节码invokestatic指令
3)当使用类或者接口的静态字段时(final常量除外,此种情况只会加载类而不会进行初始化),即使用getstatic或者putstatic指令(可以使用jclasslib软件查看生成的字节码文件),或者对该静态字段赋值(putstatic指令)。
4)当使用java.lang.reflect包中的方法反射类的方法时。如Class.forName("com.example.Test")
5)当初始化子类时,必须先初始化父类
6)作为启动虚拟机,含有main方法的那个类
7)JDK1.7开始提供的动态语言支持
java.lang.invoke.MethodHandle实例的解析结果REF_getStatic, REF_putStatic,REF_invokeStatic句柄对应的类没有初始化,则初始化。
除了以上情况属于主动使用外,其他情况均属于被动使用,被动使用不会引起类的初始化,只是加载了类却没有初始化。(这里的初始化就是类加载的第三个阶段)
二、类装载的过程
1、加载类: 处于类装载的第一个阶段
1.1 类的加载指的是将类的.class 文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在内存中创建一个java.lang.Class对象(规范中并未说明Class对象位于哪里,HotSpot虚拟机将其放在方法区中),用来分装类在方法区内的数据结构。
加载类时,JVM必须完成
1)通过类的全名,获取类的二进制数据流。
2)解析类的二进制数据流为方法区内的数据结构,也就是将类文件放入方法区中
3)创建java.lang.Class类的实例,表示该类型
1.2 加载.class 文件的方式
从本地系统中直接加载
通过网络下载.class文件
从zip,jar等文档文件中加载.class 文件
从专有数据库中提取.class文件
将Java源文件动态编译为.class 文件(动态代理,JSP(JSP文件本质上是Sevlet,最终被编译为.class文件))
2、连接
2.1 验证字节码
验证字节码文件: 当类被加载到系统后,就开始连接操作,验证就是连接的第一步
主要目的是保证加载的字节码是否符合规范
验证的步骤如图:
2.2 准备阶段
当一个类通过验证后,虚拟机就会进入准备阶段。准备阶段是正式为类变量(static修饰的变量)分配内存并设置类变量初始值,这些内存都将在方法区进行分配。这个时候进行内存分配的仅是类变量,不包括类实例变量,实例变量将会在对象实例化时随着对象一起分配在堆上。为类变量设置初始值是设为其数据类型的“零值”。
比如: public static int num = 10; 这个时候就会为num变量赋值为0
Java虚拟机为各种类型变量默认的初始值如表:
注意:java并不支持boolean类型,对于boolean类型,内部实现试Int, 由于int的默认值是0, 故对应的boolean的默认值是false。
如果类中属于常量的字段,那么常量字段也会在准备阶段被附上正确的值,这个赋值属于java虚拟机的行为,属于变量的初始化。在准备阶段,不会有任何java代码被执行。
2.3 解析类
解析阶段的任务就是将类、接口、字段和方法的符号引用直接转为直接引用。
符号引用就是一些字面量的引用。比较容易理解的就是在Class类文件中,通过常量池进行大量的符号引用。
3、初始化
为类的静态变量赋予正确的初始值。
三、类的使用和卸载
除了上面三个步骤,加载,连接,初始化,还有下面两个过程:使用和卸载
4、使用: 如类创建一个对象,调用类里的方法。
5、卸载:.class 文件加载到内存中,形成了一个自己的数据结构驻留在内存中,还可以从内存中销毁掉,称之为卸载。
卸载以后,就不能再创建类的对象了。可以重新加载到内存中。(开发人员很少使用卸载)
以上就是类加载的5个过程。
参考: https://blog.csdn.net/qq_20610631/article/details/82709187
字节码(.class)文件的加载过程的更多相关文章
- <JVM中篇:字节码与类的加载篇>03-类的加载过程(类的生命周期)详解
笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...
- <JVM中篇:字节码与类的加载篇>04-再谈类的加载器
笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...
- ELF文件的加载过程(load_elf_binary函数详解)--Linux进程的管理与调度(十三)
加载和动态链接 从编译/链接和运行的角度看,应用程序和库程序的连接有两种方式. 一种是固定的.静态的连接,就是把需要用到的库函数的目标代码(二进制)代码从程序库中抽取出来,链接进应用软件的目标映像中: ...
- <JVM中篇:字节码与类的加载篇>02-字节码指令集
笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...
- <JVM中篇:字节码与类的加载篇>01-Class字节码文件结构
笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...
- Tomcat8源码笔记(三)Catalina加载过程
之前介绍过 Catalina加载过程是Bootstrap的load调用的 Tomcat8源码笔记(二)Bootstrap启动 按照Catalina的load过程,大致如下: 接下来一步步分析加载过程 ...
- Dubbo源码分析之ExtensionLoader加载过程解析
ExtensionLoader加载机制阅读: Dubbo的类加载机制是模仿jdk的spi加载机制: Jdk的SPI扩展加载机制:约定是当服务的提供者每增加一个接口的实现类时,需要在jar包的META ...
- Spring Framework框架解析(1)- 从图书馆示例来看xml文件的加载过程
引言 这个系列是我阅读Spring源码后的一个总结,会从Spring Framework框架的整体结构进行分析,不会先入为主的讲解IOC或者AOP的原理,如果读者有使用Spring的经验再好不过.鉴于 ...
- 2、手把手教你Extjs5(二)项目中文件的加载过程
上一节中用sencha工具自动创建了一个项目,并且可以在浏览器中查看.现在我们来看看js类加载过程.如下图所示: 1、首先:浏览器中输入 localhost:1841 ,调用 index.html; ...
随机推荐
- C++创建和使用动态链接库
一个简单的动态链接库的生成和调用例子,太过简单,大神请绕道. 一.创建动态链接库 使用vs创建工程选择动态链接库. 在项目中创建源文件和头文件,并在文件中添加以下代码. 在头文件中添加以下代码 // ...
- Android笔记(四十四) Android中的数据存储——SQLite(六)整合
实现注册.登录.注销账户 MainActivity.java package cn.lixyz.activity; import android.app.Activity; import androi ...
- [https][tls] 如何使用wireshark查看tls/https加密消息--使用keylog
姊妹篇: [ipsec][strongswan] 使用wireshark查看strongswan ipsec esp ikev1 ikev2的加密内容 [https][tls] 如何使用wiresha ...
- Django中多对多关系的orm表设计
作者的管理 1.设计表结构 出版社 书籍 作者 一个出版社出版多个书籍 1对多 书籍和作者的关系:一个作者写多本书,一本书可以是多个作者写.多对多 1)创建一张表,表中多对多的数据关系.使用 多对多 ...
- SpringCloud学习心得之Eureka注册中心的基本使用
SpringCloud学习心得——Eureka注册中心 示范代码链接 定义 SpringCloud Eureka是 SpringCloud Netflix微服务套件的一部分,基于 REST 的服务 ...
- ubuntu14.04 部署nfs服务
安装nfs服务 apt-get install nfs-kernel-server 修改配置文件,共享目录为/var/www,*号可替换为客户端IP地址,*默认为任何部署了nfs客户端的IP可以挂载该 ...
- Linux iftop 安装与参数详解
介绍 iftop是一款实时流量监控工具,监控TCP/IP连接等,缺点就是无报表功能.必须以root身份才能运行. .编译安装如果采用编译安装可以到iftop官网下载最新的源码包. 安装前需要已经安装好 ...
- 批量下载oracle jdk
1.打开 https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html 2.同意条款 3. ...
- django 第四天模板渲染
今日内容 一.模板渲染 语法 {{ 变量 }} {% 逻辑 %} 1.变量 取列表中的第几个元素,用索引 <p>{{ namelist.2 }}</p> 取字典中的第几个元素用 ...
- RookeyFrame Bug 表单管理 -> 查看表单 ->编辑字段页面 JS报错
表单管理 -> 查看表单 ->编辑字段页面 小bug onchange里面直接就是方法,修改:去掉外面的function(){},直接把方法体写在onchange里面就可以了. 后台方法: ...