java虚拟机原理:类加载过程详解
作者:韩曙亮 发布时间:2023-08-09 11:35:37
目录
一、Java 类加载过程
1、字节码编译
2、加载
3、连接
4、初始化
总结
一、Java 类加载过程
1、字节码编译
编写好 Java 源码 Student.java ,
使用 javac 将上述 Java 源码编译成 Class 字节码文件 Student.class ,
2、加载
加载 : 通过 " 类加载子系统 " 将该字节码文件 , 加载到 Java 虚拟机内存中 的 方法区 , 然后开始执行 " 连接 " 操作 ,
类加载时机 : Java 程序执行时 , 并不是一开始将所有的字节码文件都加载到内存中 , 而是用到时才进行加载 ;
通过 new 关键字创建实例对象 ;
通过 Class 反射 获取类 ;
如 : Class.forName(“Xxx”) 获取类 ;
序列化 / 反序列化 ;
调用 clone 克隆对象 ;
有 main 函数的类 , 会默认自动加载 ;
调用子类 , 如果之前没有加载过父类 , 则 自动加载父类 ;
3、连接
连接操作 分为 3 3 3 个步骤 :
验证 : 对 字节码文件 进行校验 , 查看该字节码格式是否正确 , 如 : 是否以 0xCAFEBABE 开头 , 字段表 , 方发表 , 属性表 等格式是否正确 , 进行校验 ;
校验示例 : 假设校验如下字节码数据 , 原始数据是 【Java 虚拟机原理】Class 字节码二进制文件分析 一 ( 字节码文件附加信息 | 魔数 | 次版本号 | 主版本号 | 常量池个数 ) 二、字节码文件示例 章节中的 Java 源码 , Class 字节码 , 字节码附加信息 ;
在 Student 构造方法中 , 会调用到 1: invokespecial #1 父类构造方法 , 如果父类有有参的构造方法且没有声明无参构造方法 , 子类必须实现一个相同参数的构造方法 , 否则就会报错 ;
Constant pool:
#1 = Methodref #4.#17 // java/lang/Object."<init>":()V
{
public Student();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 1: 0
}
准备 : 在该阶段 , 在 方法区 中 , 为 类中的静态变量 进行内存划分 , 并对这些静态变量进行 默认值赋值 , 一般赋值 0 , null 等默认值 ; 即使静态变量 static int a = 5 已经有了赋值 , 但是在该阶段暂时给该静态变量赋值 0 ;
解析 : 将 " 常量池 " 中的 " 符号引用 " 转为 " 直接引用 " ;
符号引用 : 下面就是 常量池中的 符号引用 , 引用是 以符号的形式表示出来 的 , 这并不是内存中的引用 ; 直接引用 是 将 #1 = Methodref #4.#17 样式的 符号引用 转为 指向内存地址 的 指针引用 ; JVM 线程栈 的 栈帧 中的 动态链接 , 就是持有的一个指向内存的指针 , 该指针指向 栈帧 对应方法 在运行时 常量池中的 内存地址 ; 该内存地址是在 方法区 中的 ;
Constant pool:
#1 = Methodref #4.#17 // java/lang/Object."<init>":()V
#2 = Fieldref #3.#18 // Student.name:Ljava/lang/String;
#3 = Class #19 // Student
#4 = Class #20 // java/lang/Object
( 分析的数据是 【Java 虚拟机原理】Class 字节码二进制文件分析 一 ( 字节码文件附加信息 | 魔数 | 次版本号 | 主版本号 | 常量池个数 ) 二、字节码文件示例 章节中的 Java 源码 , Class 字节码 , 字节码附加信息 ; )
4、初始化
初始化 : 对变量进行 指定赋值 ;
如 : 有静态变量 static int a = 5
, 在 连接 过程中的 准备 阶段 , 为该变量赋值默认值 0 ; 在 初始化 阶段 , 为其赋值 代码 中设置的真正的 指定初始值 5 ;
来源:https://blog.csdn.net/shulianghan/article/details/120126911


猜你喜欢
- 本文实例为大家分享了Java工具类DateUtils的具体代码,供大家参考,具体内容如下import java.text.ParseExce
- boolean isGBK(String s) throws UnsupportedEncodingException { if(s.equ
- 场景:最新的leakCanary2.8.1:debugImplementation 'com.squareup.leakcanary
- 引言 在c#中,可能大多数人针对于多线程之间的通讯,是熟能生巧,对于AsyncLocal 和Thre
- 前言异常崩溃,是Android项目中一项比较棘手的问题,即便做了很多的try - catch处理,也不能保证上线不会崩,而且一旦出现崩溃,就
- 先给大家看下效果图:MenuPopwindow:package com.cloudeye.android.cloudeye.view;imp
- 本文实例为大家分享了java基于UDP实现在线聊天的具体代码,供大家参考,具体内容如下效果图:一、学习UDP的简单使用步骤接收端:Datag
- 前言在项目中为了灵活配置,我们常采用配置文件,常见的配置文件就比如xml和properties,springboot允许使用properti
- OleDbConnection,OracleConnection 或者SqlConnection这种连接,直接执行sql语句。现在的连接方式
- private static void 某天的起始截止时间(DateTime 哪一天, out DateTime 起始时间, out Dat
- 创建AlertDialog的步骤:创建AlertDialog.Builder对象调用Builder对象的setTitle方法设置标题,set
- 0.简介GridView 和 ListView 有共同的父类:AbsListView,因此 GridView 和 ListView 具有一定
- 具体内容如下所示:Intent.ACTION_AIRPLANE_MODE_CHANGED;//关闭或打开飞行模式时的广播Intent.ACT
- 在分支较多的时候,switch的效率比if高,在反汇编中我们即可看到效率高的原因一、switch语句1、在正向编码时,switch语句可以看
- list stream: reduce的使用stream 中的 reduce 的主要作用就是stream中元素进行组合,组合的方式可以是加减
- Zuul 简介Zuul 的主要功能是路由转发和过滤器。路由功能是微服务的一部分,比如 /api/admin 转发到到 Admin 服务,/a
- 在winform里拖入一个datagridview控件,跟一个openfiledialog控件using System;using Syst
- 本文总结三种用于安卓录屏的解决方案:adb shell命令screenrecordMediaRecorder, MediaProjectio
- 下面通过代码给大家分享下依赖注入框架Autofac的使用,具体如下所示: Autofac是一款IOC框架,比较于其他的IOC框架,
- 封装:就是把一些属性和方法封装到一个类里。 继承:就如子类继承父类的一些属性和方法。 多态:就如一个父类有多个不同特色的子类。 这里我就不多