JVM类加载机制

一、类的生命周期:

加载-》连接(验证-》准备-》解析)-》初始化-》使用-》卸载。

二、加载:

1、通过一个类的全限定名来获取定义此类的二进制字节流。

2、将这个字节流所代表的静态存储结构转化为方法区中的运行时数据结构。

3、在内存中生成一个代表这个类的Class对象,作为方法区这个类的各种数据的访问入口。

特殊:

数组类本身不通过类加载器创建,由Java虚拟机直接创建。

1、如果数据的组件类型不是引用类型,虚拟机会把数组标记为与引导类加载器关联。

2、如果数组的组件类型是引用类型,数组将在加载该组件类型的类加载器的类名称空间上被标识。

三、验证

确保Class文件的字节流中包含的信息符合当前虚拟机的要求,不会危害虚拟机自身的安全。

1、文件格式验证 ,基于二进制字节流,通过后,字节流才进入方法区,后面的3个验证阶段基于方法区的存储结构。

2、元数据验证 ,对类的元数据进行语义校验(抽象类需要实现父类或接口中要求实现的所有方法,类的父类是否集成了final类)。

3、字节码验证,对类的方法体进行校验分析,保证运行时不会危害虚拟机安全。

4、符号引用验证,保证解析能正常执行(符号引用中通过字符串描述的全限定名是否能找到对应的类;符号引用中的类、字段、方法的访问性是否可悲当前类访问)。

四、准备

准备阶段是正式为类变量(static)分配内存并设置类变量初始值(0,null)的阶段,这些变量所使用的内存将在方法区中分配,static final直接初始化。

五、解析

虚拟机将常量池中的符号引用替换为直接引用的过程。

1、类和接口的解析。

2、字段的解析。

3、类方法解析。

4、接口方法解析。

六、初始化

触发类初始化的场景:

1、使用new关键字实例化对象、读取或者设置一个类的静态字段(static final常量除外),调用类的静态方法。

2、对类进行反射调用。

3、初始化类时,有父类则先初始化父类。

4、虚拟机启动时,先初始化主类(包含main()方法)。

5、JDK 1.7动态语言支持,MethodHandle实例解析结果方法句柄对应的类要先初始化。

初始化阶段是执行类构造器<clinit>()方法的过程:

针对类变量及静态语句块,clinit方法与实例构造器不同,不需要显式的调用父类构造器,虚拟机保证父类的clinit方法在子类前,虚拟机保证一个类的clinit方法在多线程环境中被正确的枷锁、同步,多个线程同时初始化一个类,只有一个线程执行类的clinit方法。

七、类加载器

任意一个类,都需要由加载它的类加载器和这个类本身一同确立其在JVM中的唯一性。

双亲委派模型(解决了基础类的统一问题)

启动类加载器(Bootstrap ClassLoader)-》扩展类加载器(Extension ClassLoader)-》应用程序类加载器(Application ClassLoader)-》自定义类加载器。

如果一个类加载器收到了类加载的请求,首先不会自己尝试去加载这个类,而是将请求委派给父类加载器去完成,所有的加载请求最终都传送到启动类加载器,只有父加载器反馈无法加载,子加载器才会尝试自己加载。

双亲委派模型的特殊情况:

1、代码热替换、模块热部署,OSGi实现模块化热部署的关键是它自定义的类加载器机制的实现。每一个程序模块(Bundle)都有自己的类加载器,当需要更换一个Bundle时,就把Bundle连同类加载器一起替换掉以实现代码的热替换。

2、JNDI对资源进行集中管理和查找,需要调用由独立厂商实现并部署在应用程序ClassPath下的JNDI接口提供者(SPI,Service Providr Interface)的代码(JDBC),

引入线程上下文类加载器,可以通过Thread类的setContextClassLoader方法设置,如果创建线程未设置,则从线程集成,如果应用程序全局范围未设置,则默认为应用程序类加载器,JNDI服务调用这个类加载器加载所需SPI代码,父加载器请求子类加载器取完成类加载,违背双亲委派模型。

本文分享自微信公众号 - Java编程指南(JavaXxzyfx)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-09-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏网络技术联盟站

华为路由交换技术 | 网络地址转换技术NAT(Network Address Translation)详解与配置案例

NAT:(Network Address Translation) 网络地址转换技术,作用是将内网私有地址转换成公网地址,使得内网的主机可以上外网。

53720
来自专栏程序猿声

干货|十分钟教你用动态规划算法解Travelling Salesman Problem(TSP)问题,附代码……

乍一看标题,大家是不是觉得“动态规划”这四个字组合在一起有点眼熟?似乎哪会儿学过来着……但是吧,细细一琢磨,又忘了它具体是什么、怎么用、用来解决哪些问...

9630
来自专栏程序源代码

​CentOS Linux安装Oracle数据库

由于CentOS安装后差不多有4~5G,再加上Oracle等等的安装,所以请准备至少10G的硬盘空间。

23540
来自专栏Eureka伽罗的技术时光轴

Android安全-SO动态库注入

所谓的SO注入就是将代码拷贝到目标进程中,并结合函数重定向等其他技术,最终达到监控或改变目标进程行为的目的。Android是基于Linux内核的操作系统...

23320
来自专栏前端自习课

【CSS】207-深入理解z-index

在页面编写的过程中,经常需要处理元素的重叠。重叠的顺序不当则容易造成元素被错误地遮盖等现象。一般地,有很多人认为只需要指定元素的z-index即可调整重叠的顺序...

9920
来自专栏诸葛青云的专栏

为什么C语言依然是必学的编程语言,这3点告诉你答案

如今,市面上编程语言几百种,很多人觉得Python、 JAVA这种语言比较火,是不是C语言就不行了呢?

15220
来自专栏网络技术联盟站

H3CNE实验系列 | VPN (GRE)

路由器 R1 和路由器 R3 间通过其他网络相连,运行 IP 协议的似有玩了过的两个子

13940
来自专栏Java栈

Java获取本地计算机基本信息

public static List<String> getIpAddress(){

22510
来自专栏休辞醉倒

浅析变长数组(VLA)和动态数组

前天实训听见几位推免的大佬聊面试中出现了动态数组,而我们所学并没有涉及到动态数组,遂翻起了尘封已久的《C语言程序设计现代方法》以及《C Primer Plus》...

13820
来自专栏前端自习课

【CSS】202-23个CSS垂直居中技巧汇总

自古以来(是有多?~),网页CSS的垂直居中需求始终没有停过,而其困难度也始终没有让人轻松过,经过了每位开发先烈的研究后,据说CSS的垂直居中技巧已达到近十种之...

10020

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励