Java深度解析:类的生命周期与类加载过程

文章目录

    • 加载阶段
    • 连接阶段-验证
    • 连接阶段-准备
    • 连接阶段-解析
    • 初始化阶段
    • 使用
    • 卸载

最近在学习Java 虚拟机,学到了类的声明周期,有些比较难理解的点,特地来总结一下。

类的生命周期从大体上来看的话,有五个阶段,分别是加载,链接,初始化,使用,卸载。
更细分的来看的话,有七个阶段,其实就是链接阶段又分为了验证、准备、解析。
我们来详细的看看这几个阶段分别做了些什么。

加载阶段

加载阶段其实顾名思义,就是将字节码文件加载到内存中,当前字节码文件的来源有很多,可以是本地文件,可以是网络传输过来的,也可以是动态代理生成的。
在将字节码文件加载到内存之后,会将字节码 文件的信息保存到方法区中。在方法区中生成一个对象来保存这些信息,这个对象是InstanceKlass对象,这个对象包含了字节码的信息和一些其他的信息。
不仅在方法区中生成对象,还要在堆中生成一个Class对象,包括该类的一些基本信息,比如方法,字段等。
这两个对象可以相互引用,相互找到。同时这个Class对象还要存一些静态对象(JDK8)。

为什么要创建两个对象呢?用一个不是更节省内存吗?

因为InstanceKclass对象中有很多的信息,包括一些开发者不需要的信息,为了控制开发者访问数据的范围,所以创建了一个新的对象。
同时InstanceKclass创建的对象是由C++语言编写的,所以Java 语言不能直接去操作。

连接阶段-验证

这部分主要是验证字节码文件的内容是否遵守了Java 虚拟机规范,其实主要是验证文件的格式,验证主次版本号,验证元信息等等。

连接阶段-准备

准备阶段主要是给静态变量分配内存并且设置初值,如果有静态变量的话,就会在堆中创建一个区域,用于存放这个变量,然后给他赋值一个初始值。
绝大部分的初始值是0,引用类型是null

为什么在准备阶段赋值一个初始值呢?

其实就是为了覆盖之前的一些残留值。
一些特殊情况:如果静态变量用**final**修饰,在这个阶段就会给其赋值。

连接阶段-解析

这一部分主要是将符号引用转换为直接引用,因为在字节码文件中,很多的引用都是使用的符号引用,在解析阶段会将这个符号引用转换为相应的内存地址。

为什么要使用符号引用?

符号引用主要用于Java 实现动态加载类,类是在第一次使用时动态加载的,也就是说,在编译时,并不能确定所有类的加载时间和位置。因此,需要依赖符号引用来定位需要加载的类。

符号引用是怎么引用的?它是如何完成转换的?

针对符号引用来说,我们对于类,方法等一些信息,将其存在常量池中,每次需要引用这些常量吃的时候,会直接引用这些信息,只有当运行的时候,才会将这些信息转换为内存地址。
例如:

import java.util.*;
public class Main{public static void main (String[] args) {int a = 0;test();System.out.println(a);}public static void test(){System.out.println("test");}
}

我们可以使用jclasslib查看一下字节码文件:
image.png
我们可以看到,在引用方法test的时候,是传递的是#2,也就是常量池中的一个唯一标识,这个标识我们看看是代表什么。
image.png
可以看到,这个标识里面存了两个信息,一个是该方法所在的类,一个是方法的名字,他们分别标识了常量池中的两个地址,其实这两个地方存的就是类名和方法名。
我们根据类名去内存中去获取字节码信息,也就是元信息,然后根据方法表中的方法名,参数等信息找到test方法的内存地址,这样就可以运行了。

初始化阶段

初始化阶段就是会执行静态代码块的代码,然后为静态变量赋值。其实会调用clinit方法的一些操作。
这个clinit方法执行的顺序和我们编写Java 代码的顺序一致。
以下操作会导致类的初始化:

  1. 访问一个类中的静态变量或者静态方法,注意final修饰的不会进行初始化。
  2. 调用Class。forName()方法
  3. 使用new 一个新对象
  4. 执行Main方法所在的类

注意:
数组的创建不会导致类的初始化。
final修饰的变量如果赋值的不是常量,那么也会初始化。

类中的代码块

针对类中的代码块,其执行的顺序在构造函数之前。

针对有继承关系的类的初始化

  1. 直接访问父类的静态变量,子类不会初始化
  2. 子类初始化的时候,会先初始化父类。也就是说会先将父类加载到内存中。

使用

使用就是在Java 中使用这个类。

卸载

关于卸载这一部分其实主要还是类或者对象的回收,这一部分涉及到了Java 虚拟机的垃圾回收机制,所以在这一部分先不讲解,以后专门会写一下Java 虚拟机的垃圾回收机制。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/418455.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

十八周周报

文章目录 摘要文献阅读3D reconstruction of human bodies from single-view and multi-view images: A systematic review简介研究方法搜索策略选择标准搜索结果 三维重建方法单个视图中使用的技术基于参数化人体模型的回归基于非参数人体模型的回归 多个视图中使用的技术基于…

ARMv8-AArch64 的异常处理模型详解之异常类型 Exception types

异常类型详解 Exception types 一, 什么是异常二,同步异常(synchronous exceptions)2.1 无效的指令和陷阱异常(Invalid instructions and trap exceptions)2.2 内存访问产生的异常2.3 产生异常的指令2.4 调…

使用残差网络识别手写数字及MNIST 数据集介绍

MNIST 数据集已经是一个几乎每个初学者都会接触的数据集, 很多实验、很多模型都会以MNIST 数据集作为训练对象, 不过有些人可能对它还不是很了解, 那么今天我们一起来学习一下MNIST 数据集。 1.MNIST 介绍 MNIST 数据集来自美国国家标准与技术研究所, National Institute of S…

Docker 47 个常见故障的原因和解决方法

【作者】曹如熙,具有超过十年的互联网运维及五年以上团队管理经验,多年容器云的运维,尤其在Docker和kubernetes领域非常精通。 Docker是一种相对使用较简单的容器,我们可以通过以下几种方式获取信息: 1、通过docker r…

HNU-编译原理-实验1-利用FLEX构造C-Minus-f词法分析器

编译原理实验1利用FLEX构造C-Minus-f词法分析器 计科210X 甘晴void 202108010XXX 实验要求 详细的实验项目文档为 https://gitee.com/coderwym/cminus_compiler-2023-fall/tree/master/Documentations/lab1 学习和掌握词法分析程序的逻辑原理与构造方法。通过 FLEX 进行实…

[陇剑杯 2021]webshell

[陇剑杯 2021]webshell 题目做法及思路解析(个人分享) 问一:单位网站被黑客挂马,请您从流量中分析出webshell,进行回答: 黑客登录系统使用的密码是_____________。 题目思路: 分析题目&…

【蓝桥备赛】求阶乘

题目链接 求阶乘 个人想法 之前做过计算阶乘结果后面有几个0的题目,这里看到本题之后,很快就有思路了。想要得到阶乘结果有几个0,首先尾数后面的0,最小肯定是因为因子中存在10。然后,10如何得来呢? 2 * …

【面试突击】硬件级别可见性问题面试实战(中)

🌈🌈🌈🌈🌈🌈🌈🌈 欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术的推送! 在我后台回复…

有线桥接|Wifi隔了一堵墙就没信号?房间的网线口利用起来,让房间死角也有网!

前言 本篇文章是路由器有线桥接主路由,起到AP(热点)的效果 上次发布的无线桥接,使用的前提是需要把旧路由放置在主路由的信号范围内,这极大限制了桥接路由器的放置位置。 如果隔了一堵墙基本上就无法连接Wifi&#x…

STL——list

1、list介绍 1. list 是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。 2. list 的底层是带头双向循环链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后…

Docker之网络配置的使用

🎉🎉欢迎来到我的CSDN主页!🎉🎉 🏅我是君易--鑨,一个在CSDN分享笔记的博主。📚📚 🌟推荐给大家我的博客专栏《Docker之网络配置的使用》。🎯&…

Elasticsearch Index Shard Allocation 索引分片分配策略

Elasticsearch 索引分片的分配策略说明 在上一篇《索引生命周期管理ILM看完不懂你锤我 》(https://mp.weixin.qq.com/s/ajhFp-xBU1dJm8a1dDdRQQ)中,我们已经学会了索引级别的分片分配过滤属性,也就是在配置文件中指定当前节点的属…