当前位置:网站首页>JVM-类加载过程
JVM-类加载过程
2022-06-11 11:11:00 【Ther233】
前置知识
类的生命周期:
1.加载
2.连接
2.1验证
2.2准备
2.3解析
3.初始化
4.使用
5.卸载
类加载过程
类加载过程三大步骤:
1.加载
2.连接
2.1验证
2.2准备
2.3解析
3.初始化
加载
类加载过程第一步,加载,主要干了三件事:
1.通过全类名获取该类的字节码文件,并将其加载成二进制字节流
2.将字节流所代表的静态存储结构(编码结构)转换为方法区的运行时数据结构(运行时的内存结构)
3.在内存中生成一个代表该类的 Class 对象,作为方法区这些数据的访问入口
package com.tan.classloading;
//静态存储结构
public class Cola {
private int price =2;
private static int capacity = 330;
static {
int invent_date = 18860508;
}
public Cola(){
price = 3;
price = 5;
}
}
//通过查看字节码文件,观察运行时的内存结构
Classfile /D:/220106/code/Jvm/target/classes/com/tan/classloading/Cola.class
Last modified 2022-6-10; size 449 bytes
MD5 checksum e6d9a0cd5658f8b7f42c72225c62fbbe
Compiled from "Cola.java"
public class com.tan.classloading.Cola
minor version: 0
major version: 49
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #6.#20 // java/lang/Object."<init>":()V
#2 = Fieldref #5.#21 // com/tan/classloading/Cola.price:I
#3 = Fieldref #5.#22 // com/tan/classloading/Cola.capacity:I
#4 = Integer 18860508
#5 = Class #23 // com/tan/classloading/Cola
#6 = Class #24 // java/lang/Object
#7 = Utf8 price
#8 = Utf8 I
#9 = Utf8 capacity
#10 = Utf8 <init>
#11 = Utf8 ()V
#12 = Utf8 Code
#13 = Utf8 LineNumberTable
#14 = Utf8 LocalVariableTable
#15 = Utf8 this
#16 = Utf8 Lcom/tan/classloading/Cola;
#17 = Utf8 <clinit>
#18 = Utf8 SourceFile
#19 = Utf8 Cola.java
#20 = NameAndType #10:#11 // "<init>":()V
#21 = NameAndType #7:#8 // price:I
#22 = NameAndType #9:#8 // capacity:I
#23 = Utf8 com/tan/classloading/Cola
#24 = Utf8 java/lang/Object
{
public com.tan.classloading.Cola();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_2
6: putfield #2 // Field price:I
9: aload_0
10: iconst_3
11: putfield #2 // Field price:I
14: aload_0
15: iconst_5
16: putfield #2 // Field price:I
19: return
LineNumberTable:
line 9: 0
line 4: 4
line 10: 9
line 11: 14
line 12: 19
LocalVariableTable:
Start Length Slot Name Signature
0 20 0 this Lcom/tan/classloading/Cola;
static {};
descriptor: ()V
flags: ACC_STATIC
Code:
stack=1, locals=1, args_size=0
0: sipush 330
3: putstatic #3 // Field capacity:I
6: ldc #4 // int 18860508
8: istore_0
9: return
LineNumberTable:
line 5: 0
line 7: 6
line 8: 9
LocalVariableTable:
Start Length Slot Name Signature
}
SourceFile: "Cola.java"
怎么通过字节码文件查看运行时的内存结构?
首先点击Build-Build project,编译该类,去生成该类对应的字节码文件
其次在target文件夹下找到该字节码文件,右键选择open in terminal
最后在terminal中输入命令:
在命令行中显示:
javap -v Cola.class
将该字节码文件存储到指定文件中:
javap -v Cola.class >a.txt
为了更好的观察运行时的内存结构,可以在idea中下载插件:
jclasslib Bytecode Viewer
怎么使用jclasslib Bytecode Viewer去查看字节码文件的运行时的内存结构?
点击View-show bytecode with jclasslib
连接
类加载过程第二步,连接,又可以细化为三个步骤:
1.验证
目的在于确保c1ass文件的字节流中包含信息符合当前虚拟机要求,保证被加载类的正确性,不会危害虚拟机自身安全
主要包括四种验证,文件格式验证,元数据验证,字节码验证,符号引用验证
-->进行各种验证,进而保证正确加载类
2.准备
为类变量分配内存并且设置该类变量的默认初始值,即零值
这里不包含用final修饰的static,因为final在编译的时候就分配了,准备阶段会显式初始化
这里不会为实例变量分配初始化,类变量会分配在方法区中,而实例变量是会随着对象一起分配到Java堆中
-->为类变量(static修饰的变量,不包括final static修饰的,因为final在编译的时候就分配了)分配内存,并且设置类变量的默认初始值
3.解析
将常量池内的符号引用转换为直接用的过程
事实上,解析换作往往会伴随着M在执行完初始化之后再执行
符号引用就是一组符号来描述所引用的目标。符号引用的字面量形式明确定义在《Java虚拟机机范》的c1ss文件格式中。直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄
解析动作主要针对类或接口、字段、类方法、接口方法、方法类型等。对应常量池中的CONSTANT_Class_info,CONSTANT_Fieldref_info,CONSTANT_Methodref_info等
-->将Java类解析成各种成分:常量池、接口、字段、方法、属性等
注意:
加载阶段和连接阶段不是严格的前后执行关系,加载阶段和连接阶段的部分内容是交叉进行的,加载阶段可能还未结束,连接阶段可能就已经开始了
初始化
类加载过程第三步,初始化:
初始化阶段就是执行类构造器方法<c11n1t()的过程
此方法不需定义,是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来
构造器方法中指令按语句在源文件中出现的顺序执行
<c11n1t>()不同于类的构造器。(关联:构造器是虚拟机视角下的<init>())
若该类具有父类,JVM会保证子类的<c1init>()执行前,父类的<c1init>()已经执行完毕
虚拟机必须保证一个类的<c1init>()方法在多线程下被同步加锁
-->执行类构造方法<init>和初始化方法<clinit>的过程
--><clinit>不是构造器,其主要汇聚所有静态变量赋值和静态代码块,并为其赋值
注意:
<clinit> 方法在编译之后会自动生成,并且<clinit>方法是带锁线程安全,在多线程环境下进行类初始化可能会导致多个进程阻塞
JVM规定的六种必须对类进行初始化的场景:
1.遇到 new(创建对象) 、 getstatic(读取为被final修饰的类的静态变量)、putstatic(给类的静态变量赋值) 或 invokestatic(调用一个类中的静态方法) 这 4 条直接码指令的时候
e.g:创建对象
2.使用 java.lang.reflect 包的方法对类进行反射调用
e.g:Class.forname("xxx")、newInstance()
3.初始化一个类,其继承了一个类,并且其父类还未初始化,则会先触发该父类的初始化
4.当虚拟机开始运行,虚拟机会先初始化要执行的主类 (程序入口)
5.要使用MethodHandle 和 VarHandle (轻量级的反射调用机制),就必须先使用 findStaticVarHandle 来初始化要调用的类
6.当一个接口中定义了 JDK8 新加入的默认方法,即:被 default 关键字修饰的接口方法,如果该接口的实现类发生了初始化,那该接口必须要在其之前被初始化
边栏推荐
- 拆分数据---水平拆分和纵向拆分
- Inventory of the 9 most famous work task management software at home and abroad
- 2022年最好的年金险产品是什么?
- Exness: the progress of Russia Ukraine negotiations is limited, and the RBA's decision remains unchanged
- 数字藏品app小程序公众号系统开发
- The complete manual of the strongest Flink operator is a good choice for the interview~
- 为WordPress相关日志插件增加自动缩略图功能
- Vscode——vscode 多窗口名字配置成项目名字
- Development of official account system for digital collection app applet
- NFT digital collection app system construction
猜你喜欢

Problems encountered when using nailing intranet to penetrate and upload PHP projects

Application of volatile in single chip microcomputer

MyCat-分库分表

Method of converting VOC format data set to Yolo format data set

The first day of the new year | at 8:00 p.m. tomorrow, pulsar Chinese developer and user group meeting registration

Iterator mode -- battlefield autumn point

How programmers do sidelines

Adapter mode -- can you talk well?

VOC格式数据集转yolo格式数据集的方法

外观模式--在各种套餐中早就用到啦!
随机推荐
Introduction to thread pool: ThreadPoolExecutor
Node连接MySql数据库写模糊查询接口
Etcd的运行时重配置
迭代器模式--沙场秋点兵
WP Super Cache静态缓存插件简明使用教程
Iterator mode -- battlefield autumn point
李飞飞:我更像物理学界的科学家,而不是工程师|深度学习崛起十年
985 University doctors became popular because of their thanks in classical Chinese! The tutor commented that he not only wrote well in sci
装饰模式--小美的生日蛋糕
Exploration of kangaroo cloud data stack on spark SQL optimization based on CBO
拆分数据---水平拆分和纵向拆分
数据库系统概论 ---- 第二章 -- 关系数据库(2.4 关系代数)
Vscade -- vscode multi window name is configured as project name
企业微信小程序避坑指南,欢迎补充。。。
my.cnf中 [mysql]与[mysqld] 的区别 引起的binlog启动失败的问题
为WordPress相关日志插件增加自动缩略图功能
Summary of information of main account of Chia Tai futures on Wednesday in advance
Is it safe for Xiaobai to open an account directly on the flush?
The first day of the new year | at 8:00 p.m. tomorrow, pulsar Chinese developer and user group meeting registration
CPU负载怎么理解