深入浅出Java类加载过程
学习笔记二之Java虚拟机中类加载的过程
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现这个类进行初始化。
1. 加载
加载,是指Java虚拟机查找字节流(查找.class文件),并且根据字节流创建java.lang.Class对象的过程。这个过程,将类的.class文件中的二进制数据读入内存,放在运行时区域的方法区内。然后在堆中创建java.lang.Class对象,用来封装类在方法区的数据结构。
类加载阶段:
(1)Java虚拟机将.class文件读入内存,并为之创建一个Class对象。
(2)任何类被使用时系统都会为其创建一个且仅有一个Class对象。
(3)这个Class对象描述了这个类创建出来的对象的所有信息,比如有哪些构造方法,都有哪些成员方法,都有哪些成员变量等。
Student类加载过程图示:

2. 链接
链接包括验证、准备以及解析三个阶段。
(1)验证阶段。主要的目的是确保被加载的类(.class文件的字节流)满足Java虚拟机规范,不会造成安全错误。
(2)准备阶段。负责为类的静态成员分配内存,并设置默认初始值。
(3)解析阶段。将类的二进制数据中的符号引用替换为直接引用。
说明:
符号引用。即一个字符串,但是这个字符串给出了一些能够唯一性识别一个方法,一个变量,一个类的相关信息。
直接引用。可以理解为一个内存地址,或者一个偏移量。比如类方法,类变量的直接引用是指向方法区的指针;而实例方法,实例变量的直接引用则是从实例的头指针开始算起到这个实例变量位置的偏移量。
举个例子来说,现在调用方法hello(),这个方法的地址是0xaabbccdd,那么hello就是符号引用,0xaabbccdd就是直接引用。
在解析阶段,虚拟机会把所有的类名,方法名,字段名这些符号引用替换为具体的内存地址或偏移量,也就是直接引用。
3. 初始化
初始化,则是为标记为常量值的字段赋值的过程。换句话说,只对static修饰的变量或语句块进行初始化。
如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。
如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行。
4. 小结
类加载过程只是一个类生命周期的一部分,在其前,有编译的过程,只有对源代码编译之后,才能获得能够被虚拟机加载的字节码文件;在其后还有具体的类使用过程,当使用完成之后,还会在方法区垃圾回收的过程中进行卸载(垃圾回收)。
5. 附录
常见问题:在自己的项目里新建一个java.lang包,里面新建了一个String类,能代替系统String吗?
不能,因为根据类加载的双亲委派机制,会将请求转发给父类加载器,父类加载器发现冲突了String就不会加载了。
6. 参考
【1】 周志明. 深入理解Java虚拟机:JVM高级特性与最佳实践(第二版)【M】.北京:机械工业出版社,2013
【2】爱飞翔,周志明(译).Java虚拟机规范(Java SE 8版)【M】.北京:机械工业出版社,2015.
【3】https://blog.csdn.net/ln152315/article/details/79223441
【4】https://blog.csdn.net/sinat_38259539/article/details/71794617
深入浅出Java类加载过程的更多相关文章
- 【Java_基础】java类加载过程与双亲委派机制
1.类的加载.连接和初始化 当程序使用某个类时,如果该类还未被加载到内存中,则系统会通过加载.连接.初始化三个步骤来对类进行初始化.如果没有意外,jvm将会连续完成这三个步骤,有时也把这三个步骤统称为 ...
- java 类加载过程
1. 使用命令行查看类加载过程,在eclipse测试类的run configuration中配置-verbose:class或者-verbose,如下图所示: 运行结果如下所示: [Opened D: ...
- Java类加载过程及static详解
类从被加载到JVM中开始,到卸载为止,整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载七个阶段. 其中类加载过程包括加载.验证.准备.解析和初始化五个阶段. 类加载器的任务就是根据一个类的 ...
- java类加载过程以及双亲委派机制
前言:最近两个月公司实行了996上班制,加上了熬了两个通宵上线,状态很不好,头疼.牙疼,一直没有时间和精力写博客,也害怕在这样的状态下写出来的东西出错.为了不让自己荒废学习的劲头和习惯,今天周日,也打 ...
- java类加载过程
类(型)的生命周期--装载.连接.初始化.卸载 Java虚拟机通过装载.连接和初始化一个Java类型,使该类型可以被正在运行的Java程序所使用. 1. 装载 装载阶段包括三个基本动作: ...
- 从一道面试题来认识java类加载时机与过程
说明:本文的内容是看了<深入理解Java虚拟机:JVM高级特性与最佳实践>后为加印象和理解,便记录了重要的内容. 1 开门见山 以前曾经看到过一个java的面试题,当时觉得此题很简单,可 ...
- java类加载时机与过程
转自:http://www.tuicool.com/articles/QZnENv 说明:本文的内容是看了<深入理解Java虚拟机:JVM高级特性与最佳实践>后为加印象和理解,便记录了重要 ...
- java 虚拟机内存划分,类加载过程以及对象的初始化
涉及关键词: 虚拟机运行时内存 java内存划分 类加载顺序 类加载时机 类加载步骤 对象初始化顺序 构造代码块顺序 构造方法 顺序 内存区域 java内存图 堆 方法区 虚拟机栈 本地 ...
- 【深入Java虚拟机】一 JVM类加载过程
首先Throws(抛出)几个自己学习过程中一直疑惑的问题: 1.什么是类加载?什么时候进行类加载? 2.什么是类初始化?什么时候进行类初始化? 3.什么时候会为变量分配内存? 4.什么时候会为变量赋默 ...
随机推荐
- SpringMVC的配置和使用
SpringMVC的配置和使用 什么是SpringMVC? SpringMVC是Spring家族的一员,Spring是将现在开发中流行的组件进行组合而成的一个框架!它用在基于MVC的表现层开发,类似于 ...
- hibernate封装Until工具类
public class HibernateUntil { private static SessionFactory sessionfaction; //一个web项目确保只调用一个sessionf ...
- 小程序textarea完美填坑
相信做微信小程序的码友们都被textarea这个原生组件坑过,什么placeholder位置错乱,穿透弹窗或遮罩层,ios上输入法弹起后换行输入内容遮挡,删除输入内容时内容被遮挡等等... 反正综上所 ...
- [Swift]LeetCode22. 括号生成 | Generate Parentheses
Given n pairs of parentheses, write a function to generate all combinations of well-formed parenthes ...
- [Swift]LeetCode348. 设计井字棋游戏 $ Design Tic-Tac-Toe
Design a Tic-tac-toe game that is played between two players on a n x n grid. You may assume the fol ...
- [Swift]LeetCode851. 喧闹和富有 | Loud and Rich
In a group of N people (labelled 0, 1, 2, ..., N-1), each person has different amounts of money, and ...
- shell脚本中单双引号疑惑
工作中常用到shell脚本,遇到了一个疑惑,求解. 常见的解释: 单引号字符串的限制: 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的: 单引号字串中不能出现单独一个的单引号(对单 ...
- Ubuntu12.04中的虚拟机安装Ubuntu16.04,并实现远程控制16.04
目录 1.设置网络连接 1.1 VMware虚拟机网络地址设置 1.2 设置虚拟机内Ubuntu16.04的网络模式 未开机状态下 开机状态下 1.3 查看虚拟机中Ubuntu16.04的IP 2.进 ...
- [Abp 源码分析]五、系统设置
0.简要介绍 Abp 本身有两种设置,一种就是 上一篇文章 所介绍的模块配置 Configuration,该配置主要用于一些复杂的数据类型设置,不仅仅是字符串,也有可能是一些 C# 运行时的一些变量. ...
- .NET Core实战项目之CMS 第十一章 开发篇-数据库生成及实体代码生成器开发
上篇给大家从零开始搭建了一个我们的ASP.NET Core CMS系统的开发框架,具体为什么那样设计我也已经在第十篇文章中进行了说明.不过文章发布后很多人都说了这样的分层不是很合理,什么数据库实体应该 ...