文章目录

  • 简介
  • 加载
    • 运行时常量池
    • 类加载器
  • 链接
    • 验证
    • 准备
    • 解析
  • 初始化
  • 总结

简介

有了java class文件之后,为了让class文件转换成为JVM可以真正运行的结构,需要经历加载,链接和初始化的过程。

这三个过程是怎么工作的呢?在本文中你将会找到答案。

加载

JVM可以分为三大部分,五大空间和三大引擎,要讲起来也不是特别复杂,先看下面的总体的JVM架构图。

从上面的图中,我们可以看到JVM中有三大部分,分别是类加载系统,运行时数据区域和Execution Engine。

加载就是根据特定名称查找类或者接口的二进制表示,并根据此二进制表示来创建类和接口的过程。

运行时常量池

我们知道JVM中有一个方法区的区域,在JDK8中,方法区的实现叫做元空间。这个元空间是存放在本地内存中的。

方法区中存放着每个class对应的运行时常量池。

当类或者接口创建的时候,就会通过class文件中定义的常量池来构建运行时常量池。

运行时常量池中有两种类型,分别是symbolic references符号引用和static constants静态常量。

其中静态常量不需要后续解析,而符号引用需要进一步进行解析处理。

静态常量分为两个部分:String常量和数字常量。

String常量是对String对象的引用,是从class中的CONSTANT_String_info结构体构建的。

数字常量是从class文件中的CONSTANT_Integer_info, CONSTANT_Float_info, CONSTANT_Long_info和 CONSTANT_Double_info 构建的。

符号引用也是从class中的constant_pool中构建的。

对class和interface的符号引用来自于CONSTANT_Class_info。

对class和interface中字段的引用来自于CONSTANT_Fieldref_info。

class中方法的引用来自于CONSTANT_Methodref_info。

interface中方法的引用来自于CONSTANT_InterfaceMethodref_info。

对方法句柄的引用来自于CONSTANT_MethodHandle_info。

对方法类型的引用来自于CONSTANT_MethodType_info。

对动态计算常量的符号引用来自于CONSTANT_MethodType_info。

对动态计算的call site的引用来自于CONSTANT_InvokeDynamic_info。

类加载器

类是怎么创建的呢?类的创建可以是由其他类调用该类的初始化方法来创建,也可以通过反射来创建。

类其实又可以分为两种,一种是数组类,一种是非数组类。

对于非数组类,因为他们有相应的二进制表示,所以是通过类加载器加载二进制表示来创建的。

而对于数组类,因为他们没有外部的二进制表示,所以数组类是由java虚拟机创建的。

java虚拟机中的类加载器又有两种,一种是虚拟机提供的引导类加载器,一种是用户自定义的类加载器。

如果是用户自定的类加载器,那么应该是ClassLoader的一个实现。用户自定义类加载器主要是为了扩展java虚拟机的功能,以支持动态加载并创建类。

链接

链接是为了让类或者接口可以被java虚拟机执行,而将类或者接口并入虚拟机运行时状态的过程。

链接具体的工作包括验证和准备类或者接口。而解析这个类或者接口中的符号引用是链接过程中的可选部分。

如果java虚拟机选择在用到类或者接口中的符号引用时才去解析他们,这叫做延迟解析。

如果java虚拟机在验证类的时候就解析符号引用,这就叫做预先解析。

验证

验证主要是为了保证类和接口的二进制表示的结构正确性。

如果类或者接口的二进制表示不满足相应的约束,则会抛出VerifyError异常。

准备

准备主要是创建类或者接口的静态字段,并使用默认值来初始化这些字段。

解析

解析是指根据运行时常量池中的符号引用来动态决定其具体值的过程。

在执行java虚拟机指令:

anewarray,checkcat, getfield, getstatic, instanceof, invokedynamic, invokeinterface, invokespecial, invokestatic, invokevirtual, ldc, ldc_w, multianewarray, new , putfield和putstatic这些指令的时候,都会去将符号引用指向运行时常量池,从而需要对符号引用进行解析。

解析可以分为类和接口的解析,字段解析,普通方法的解析,接口方法解析,方法类型和方法句柄解析,调用点限定符解析这几种。

初始化

类或者接口的初始化是指执行类或者接口的初始化方法。

只有下面的几种情况,类或者接口才会被初始化:

  1. 执行需要引用类或者接口的java虚拟机指令(new,getstatic, putstatic, invokestatic)的时候。
  2. 初次调用java.lang.invoke.Methodhandle实例的时候。
  3. 调用类库中的某些反射方法的时候。
  4. 对类的某个子类进行初始化的时候。
  5. 被选定为java虚拟机启动时候的初始类的时候。

总结

class文件经过加载,链接和初始化之后,就可以提供给JVM在运行时使用了。

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/jvm-class-load-link-ini/

本文来源:flydean的博客

欢迎关注我的公众号:程序那些事,更多精彩等着您!

JVM详解之:类的加载链接和初始化相关推荐

  1. win7下计划任务schtasks使用详解及错误:无法加载列资源的解决方法1

    win7下计划任务schtasks使用详解及"错误:无法加载列资源"的解决方法1 2011-12-10 20:33 schtasks 命令简述: 安排命令和程序,使其定期运行或在指 ...

  2. linux直接运行程序加载动态库失败,扣丁学堂Linux培训详解程序运行时加载动态库失败解决方法...

    今天扣丁学堂Linux培训老师给大家介绍一下关于Linux程序运行时加载动态库失败的解决方法,希望对同学们学习有所帮助,下面我们一起来看一下吧. Linux下不能加载动态库问题 当出现下边异常情况 . ...

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

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

  4. 类的加载连接和初始化

    类的加载.连接和初始化 ​ 当Java程序中需要使用到某个类时,虚拟机会保证这个类已经被加载.连接和初始化.而连接又包含验证.准备和解析这三个子过程,这个过程必须严格的按照顺序执行. 类的加载 ​ 通 ...

  5. Cocos2d之Texture2D类详解之将文件加载成Texture2D对象

    一.声明 笔者以cocos2d框架cocos2d-x-3.3rc0版本的源码做分析.本文为笔者原创,允许转载和分享,只要注明文章出处即可. 二.简介 Texture2D类简介 Texture2D类允许 ...

  6. 《Windows驱动开发技术详解》之编程加载NT式驱动

    之前我们加载驱动都是利用INSTDRV这个应用,其原理是在注册表中写入相应的字段,这一节我们手动编写代码去加载驱动,其原理类似: 设备驱动程序的动态加载主要由服务控制管理程序(Service Cont ...

  7. Web.xml配置详解之context-param (加载spring的xml,然后初始化bean看的)

    http://www.cnblogs.com/goody9807/p/4227296.html(很不错啊) 容器先加载spring的xml,然后初始化bean时,会为bean赋值,包括里面的占位符 转 ...

  8. Android:ViewPager详解(异步网络加载图片,带图片缓存,并带导航小圆点)

    android 应用中,如欢迎指引页面, 和图片轮播功能, 或者更多的内容在一页显示不了,要分成多个页面,这时候viewpager是很好用的. 首先看下效果: 下面是一个例子,带异步网络加载图片,并带 ...

  9. php获取laydate,详解关于laydate.js加载laydate.css路径错误问题

    laydate.js是属于Javascript系列的一款日期控件与时间插件,laydate.js支持兼容IE6在内的主流浏览器.laydate.js经过贤心大大的重写之后功能越来越强大,用起来也愈渐灵 ...

最新文章

  1. 数据库经典书籍--SQL必知必会
  2. 罗永浩直播带货花落谁家?不止是价高者得之
  3. java for循环遍历解释,三种for循环遍历
  4. Copy++ 复制 PDF、CAJ 内容时,自动删除空格、空行,以及自动翻译[Win]
  5. 防止病毒迷惑了您的眼睛
  6. layui table异步调用数据的时候,数据展示不出来现象解决方案
  7. 为什么说只有深度思考才能让你持续赚到钱?
  8. PHP之JWT接口鉴权(二) 自定义错误异常
  9. 强悍的电子邮件地址(email address)正则表达式
  10. java怎么打印课程表_自明排课系统如何打印?教你打印课表的方法
  11. QComboBox下拉框
  12. 华为开启管理员模式_华为设备管理员级别与其对应的权限
  13. python 计算字符串表达式_python计算数学表达式
  14. Word 2010如何对论文中参考文献进行标注
  15. 可汗学院公开课——统计学学习:35-46
  16. 35 岁程序员,年后第一天被辞退
  17. c++音乐播放所需要的头文件和库文件
  18. XSS钓鱼攻击演示。
  19. Python_xlwings小技巧(range,带格式复制粘贴)
  20. CADS Config

热门文章

  1. c语言程序设计科学出版色,C语言程序设计9787030330123张淑华科学出版社
  2. 33.文件与 IO.rs
  3. jsoncpp和rapidjson哪个好用?
  4. boost.asio系列——io_service
  5. 棋牌游戏服务器架构: 详细设计(一) 内核设计
  6. c++继承:共有、私有、保护继承
  7. Python 获取指定文件夹下的目录和文件
  8. “云端一体”的智能媒体生产制作演讲之路
  9. 音视频技术开发周刊 | 136
  10. 花椒web端实时互动流媒体播放器