java类生命周期,类的“加载,连接,初始化,使用,卸载过程”详解
“ 如果说核心类库的 API 比做数学公式的话,那么 Java 虚拟机的知识就好比公式的推导过程”
每本Java入门书籍在介绍Java这门语言的时候都会提到Java跨平台,“一次解释,到处运行的特点“,功臣就是jvm(Java Virtual Machine,Java虚拟机)。
但是,如果将jvm只与Java语言绑定在一起,那么理解就过于狭隘了,Java虚拟机发展到现在已经脱离了Java语言,形成了一套相对独立,高性能的执行方案。

除了以上提到的几种语言之外,scala,热门的kotlin都可以运行在jvm上面。
01 类生命周期
类从被加载到虚拟内存中开始,到卸载内存为止,它的整个生命周期包括:

小提示:
1.加载阶段和连接阶段有时候是交叉进行的,不需要等到完全加载结束。
2. 解析阶段有时候可以再初始化之后再做。Jvm仅仅规定了:如果某些字节码使用了符号引用,那么在执行这些字节码之前,需要完成对这些符号引用的解析。
3. 但是这些过程总的开始时间和完成时间都是上图固定顺序。
4. 这里的“加载阶段”和我们常说的“类加载”是两回事,“类加载”指的是虚线框中三部分加起来。
02 连接(Linking)
验证:
当一个类被加载之后,必须要验证一下这个类是否合法,比如这个类是不是符合字节码的格式、变量与方法是不是有重复、数据类型是不是有效、继承与实现是否合乎标准等等。
我们平常写代码很多时候第一步都是写校验,jvm也是这个思路,Java 编译器生成的类文件必然满足 Java 虚拟机的约束条件,但是为了防止“解字节码注入”。
准备:
就是为类的静态变量分配内存并设为 jvm默认 的初值,而不是我们设置的,我们设置的会在后面一个阶段“初始化”期间来做,对于非静态的变量,则不会为它们分配内存。
jvm默认的初值是这样的:
基本类型(int、long、short、char、byte、boolean、float、double)的默认值为0。其中boolean只有true,false两种类型,对应到jvm值分别是数据1,0。
引用类型(对象,数组)的默认值为null。
构造其他跟类层次相关的数据结构,比如说用来实现虚方法的动态绑定的方法表。
在 class 文件被加载至 Java虚拟机之前,这个类无法知道其他类及其方法、字段所对应的具体地址,甚至不知道自己方法、字段的地址。因此,每当需要引用这些成员时,Java 编译器会生成一个符号引用。在运行阶段,这个符号引用一般都能够无歧义地定位到具体目标上。
解析:
上面说到的“在运行阶段,这个符号引用一般都能够无歧义地定位到具体目标上”,就是在解析阶段进行的符号解析。
这个阶段目的正是将常量池中的符号引用转换解析成为实际引用。在解析阶段,jvm会将所有的类或接口名、字段名、方法名转换为具体的内存地址,从而让用到了别的类或者接口的类能找到和加载其他的类/接口。
如果符号引用指向一个未被加载的类,或者未被加载类的字段或方法,那么解析将触发这个类的加载(但未必触发这个类的链接以及初始化。)
03 初始化
在 Java 代码中,如果要初始化一个静态字段,我们可以在声明时直接赋值,也可以在静态代码块中对其赋值。除了final static修饰的常量,直接赋值操作以及所有静态代码块中的代码,则会被 Java 编译器置于同一方法中,并把它命名为 < clinit >。
类加载的最后一步是初始化,目的便是为标记为常量值的字段赋值,以及执行 <clinit > 方法的过程。Java 虚拟机会通过加锁来确保类的 < clinit > 方法仅被执行一次。
类初始化的触发情况:
当虚拟机启动时,初始化用户指定的主类(main函数);
当遇到用以新建目标类实例的 new 指令时,初始化 new 指令的目标类;
当遇到调用静态方法的指令时,初始化该静态方法所在的类;
当遇到访问静态字段的指令时,初始化该静态字段所在的类;
子类的初始化会触发父类的初始化;
如果一个接口定义了 default 方法,那么直接实现或者间接实现该接口的类的初始化,会触发该接口的初始化;
使用反射 API 对某个类进行反射调用时,初始化这个类;
当初次调用 MethodHandle 实例时,初始化该 MethodHandle 指向的方法所在的类。
设计模式中单例延迟加载,便是充分利用了这个特点。
04 卸载
那么多的类,什么时候卸载谁呢?关于卸载谁,满足如下条件:
· 该类所有的实例都已经被回收,也就是java堆中不存在该类的任何实例;
· 加载该类的ClassLoader已经被回收;
· 该类对应的java.lang.Class对象没有任何地方被引用,无法在任何地方通过反射访问该类的方法。
关于什么时候卸载,当以上条件都满足了,垃圾回收时候回在方法区清空类信息进行卸载,英雄迟暮,这个类的一生也就走到了尽头了。
有错欢迎私我指正

java类生命周期,类的“加载,连接,初始化,使用,卸载过程”详解的更多相关文章
- (转)JVM类生命周期概述:加载时机与加载过程
原文地址: http://blog.csdn.net/justloveyou_/article/details/72466105 JVM类加载机制主要包括两个问题:类加载的时机与步骤 和 类加载的方式 ...
- JVM类生命周期概述:加载时机与加载过程
一个.java文件在编译后会形成相应的一个或多个Class文件,这些Class文件中描述了类的各种信息,并且它们最终都需要被加载到虚拟机中才能被运行和使用.事实上,虚拟机把描述类的数据从Class文件 ...
- iOS开发——加载、滑动翻阅大量图片解决方案详解
加载.滑动翻阅大量图片解决方案详解 今天分享一下私人相册中,读取加载.滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制. 我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清 ...
- java Spring系列之 配置文件的操作 +Bean的生命周期+不同数据类型的注入简析+注入的原理详解+配置文件中不同标签体的使用方式
Spring系列之 配置文件的操作 写在文章前面: 本文带大家掌握Spring配置文件的基础操作以及带领大家理清依赖注入的概念,本文涉及内容广泛,如果各位读者耐心看完,应该会对自身有一个提升 Spri ...
- Android Fragment生命周期及静态加载
一个Fragment必须总是被嵌入到一个Activity中,它的生命周期直接被其所属的宿主Activity生命周期影响,它的状态会随宿主的状态变化而变化. 要创建一个Fragment 必须创建一个Fr ...
- Vue生命周期钩子函数加载顺序的理解
Vue实例有一个完整的生命周期,也就是从开始创建.初始化数据.编译模板.挂载Dom.渲染→更新→渲染.卸载等一系列过程,我们称这是Vue的生命周期.通俗说就是Vue实例从创建到销毁的过程,就是生命周期 ...
- Android 平滑图片加载和缓存库 Glide 使用详解
在图片加载库烂大街的今天,选择一个适合自己使用的图片加载库已经成为了每一个Android开发者的必经之路.现在市面上知名的图片加载库有UIL,Picasso,Volley ImageLoader,Fr ...
- [Aaronyang] 写给自己的WPF4.5 笔记6[三巴掌-大数据加载与WPF4.5 验证体系详解 2/3]
我要做回自己--Aaronyang的博客(www.ayjs.net) 博客摘要: Virtualizing虚拟化DEMO 和 大数据加载的思路及相关知识 WPF数据提供者的使用ObjectDataPr ...
- Linux USB驱动学习总结(三)---- USB鼠标的加载、初始化和通信过程
1.usbmouse的定义:usb鼠标既包含usb设备(usb_device)的属性也包含input输入设备(input_dev)的属性 struct usb_mouse { ];///USB鼠标设备 ...
随机推荐
- 服务守护DOS脚本
创建一个批处理文件,复制以下内容至文件中并保存,右键文件名,以管理员身份运行. @@@code @echo off @echo 请使用管理员身份运行此脚本 rem 运行前先打开文件修改下列变量: ...
- leetcode——链表
206. 反转链表(易) 反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->N ...
- ReactNative: 使用尺寸类Dimensions获取屏幕尺寸
一.简介 在前面创建使用组件时,虽然使用的都是伸缩盒子布局,但是很少使用宽高来进行绝对定位.在iOS中可以通过UIScreen控件获取当前屏幕的宽高,同样地,在RN中提供了一个尺寸组件Dimensio ...
- Feign Ribbon Hystrix 三者关系 | 史上最全, 深度解析
史上最全: Feign Ribbon Hystrix 三者关系 | 深度解析 疯狂创客圈 Java 分布式聊天室[ 亿级流量]实战系列之 -25[ 博客园 总入口 ] 前言 疯狂创客圈(笔者尼恩创建的 ...
- C++继承产生的问题
今天写代码,用到了继承,忘了将父类中的私有成员改为protected,结果一调用父类地函数后,子类中的root指针直接变为了父类中的空的root.私有成员在继承后依然会保留,占一定的内存空间,但却没有 ...
- Java描述设计模式(11):观察者模式
本文源码:GitHub·点这里 || GitEE·点这里 一.观察者模式 1.概念描述 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.观察者模式定义了一种一对多 ...
- 基于STM32F429的内存管理
1.内存管理介绍 内存管理,是指软件运行时对计算机内存资源的分配和使用的技术.其最主要的目的是如何高效,快速的分配,并且在适当的时候释放和回收内存资源. 内存管理的实现方法有很多种,他们其实最终都是要 ...
- Python菜鸟文本处理4种方法
自从认识了python这门语言,所有的事情好像变得容易了,作为小白,逗汁儿今天就为大家总结一下python的文本处理的一些小方法. 话不多说,代码撸起来. python大小写字符互换 在进行大小写互换 ...
- Java - 包装类 常量池
概述: 在Java中存在一些基本数据类型,这些基本数据类型变量,不能像其他对象一样调用方法,属性.... 一些情况下带来一些问题,包装类就是为了解决这个问题而出现 包装类可以使得这些基础数据类型,拥有 ...
- 零基础建站如何配置PHP运行环境 几种服务器环境配置的选择和方法
上次给大家分享了小白建站如何选择虚拟空间及服务器,及购买域名的基础知识,这些是硬性要求,你的网站要想运行起来,硬件只是基础,真正的技术是软件,关于PHP软件开发技术,后面我们会慢慢的分享给大家,今天主 ...