Klass模型与类加载的详细机制

2023-10-30 05:10

本文主要是介绍Klass模型与类加载的详细机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

klass模型是jvm中的数据类型 这个数据类型表示的是一个java类 java语言是在jvm中运行而jvm是不认识java代码的我们使用javac编译的class文件jvm是不认识的 所以有一个类加载的动作 这个动作就是把class字节码拼装成一个klass类型 这个klass类型是c++中的一个类 klass里面有java类中的所有信息比如它的属性 方法 修饰符等成为类的元信息 这些信息放在元空间中 通过下面的klass类的继承关系图可以看出
在这里插入图片描述
metaspace中文意思就是元空间 meatadata中文意思元数据
klass是c++中表示java类的数据类型 klass下面又分为普通类型与数组类型
普通类型就是我们自己定义的java类一个java类就是一个instanceKlass这个东西是放在方法区中 然后一个java类的对象就是一个instanceMirrorKlass它是放在堆中
而数组类型又分为两种TypeArrayKlass用来表示一个基本数据类型的数组 ObjArrayKlass表示一个引用类型的数组 数组是一个动态的数据类型 数组会在jvm运行它的那一刻进行创建 否则它没有实体

类的加载过程
类的加载由五个部分加载、验证、准备、解析、初始化

加载就是把硬盘上的class文件加载到内存 然后把它二进制流中的数据读取成一个klass 这时的加载只是加载了java类的信息 不包含属性

验证就是验证这个class符不符合要求

准备这一步把静态变量赋初值
在这里插入图片描述
上面是静态变量的默认值 静态变量会存放在class对象中 然后准备这一步的作用
如果在java代码中写static int a; 它不会在clinit中把这个静态变量赋值的操作写进去 clinit是编译后的静态代码块一个java类只会生成一个静态代码块也就是只会生成一次clinit 生成一次之后只会往clinit中按着顺序往里添加被static修饰的代码 像a这样的写法如果没有准备操作就不会往clinit中添加然后a就会被丢失 static int b = 0;这样写 clinit中就会有b=0这样的代码 这个clinit会在初始化的时候调用 在class加载的时候只加载了类信息属性没有被加载 而static是类加载的时候就会被创建可以直接用类名点属性名 看类的加载机制这5步只有在准备与初始化执行静态方法的时候才有赋值的动作 而初始化执行的静态代码块是在java编译的时候生成 它生成的机制是静态属性必须有赋值操作 所以说如果没有准备操作a就会被丢失 如果在类加载的过程中没有赋值的操作就不会放到klass中 放不到klass中也就意味着在java类加载到堆中的时候也是什么变量都没有的 准备这一步操作就是为了可以把静态变量放到klass中
如果被final修饰,在编译的时候会给属性添加ConstantValue属性,准备阶段直接完成赋值,即没有赋初值这一步

解析

解析就是把符号引用变为直接引用 比如java代码编制之后会把 int a = 3 这个3会写到常量池 常量池会给3分配一个地址 而符号引用就是a = 3在常量值中的地址,直接引用是指向运行时常量池 运行时常量池就是把常量池中的3变成了存放3的内存地址 然后就成了a=3的内存内地这样叫直接引用

初始化

执行静态代码块 完成静态变量的赋值 它是在jvm层面加锁的 所以在java中new对象的时候会出现死锁比如
现在有线程a跟b
a的run方法中是先让它睡眠1毫秒然后创建b的对象 就是new b();
b的run方法中是创建a对象就是new a();
然后在main方法中执行a与b的start方法 先让a执行start()方法 这样就会有很大几率触发创建对象的死锁

还有如果静态属性的位置有锁变化会导致最终的结果发生变化

比如

public class A{static int a;static A a = new A();stataic int b = 1;public A(){a++;b++;}
}

然后在main方法中打印 属性a与属性b他们的结果是 1跟1 这样的现象导致的原因就是 属性a没有赋值就不会生成到clinit中 然后clinit会根据代码顺序生成 也就是new A()操作会在第一个 a是在准备阶段赋初值是0然后b也在准备节点赋初值是0 然后到了初始化这里 执行clinit静态代码块首先执行new A()在A的构造方法中进行了a与b的自增这时都是1然后就执行完 执行完new A() 之后就执行b=1;的赋值操作 所以就导致了结果是1,1

执行类的静态代码块 clinit
*

  • 1、如果没有静态属性、有静态属性但无赋值操作、静态代码段,生成的字节码文件中就没有clinit方法块
  • 2、final修饰,不会在clinit方法块中体现
  • 3、一个字节码文件只有一个clinit方法块
  • 4、clinit方法块中生成的代码顺序与Java代码的顺序是一致的。这个会影响程序最终结果

这篇关于Klass模型与类加载的详细机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/305764

相关文章

IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤及问题解决

《IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决》:本文主要介绍IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决,本文分步骤结合实例给大... 目录步骤 1:创建 Maven Web 项目步骤 2:添加 Spring MVC 依赖1、保存后执行2、将新的依赖

SpringBoot中配置文件的加载顺序解读

《SpringBoot中配置文件的加载顺序解读》:本文主要介绍SpringBoot中配置文件的加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot配置文件的加载顺序1、命令⾏参数2、Java系统属性3、操作系统环境变量5、项目【外部】的ap

如何为Yarn配置国内源的详细教程

《如何为Yarn配置国内源的详细教程》在使用Yarn进行项目开发时,由于网络原因,直接使用官方源可能会导致下载速度慢或连接失败,配置国内源可以显著提高包的下载速度和稳定性,本文将详细介绍如何为Yarn... 目录一、查询当前使用的镜像源二、设置国内源1. 设置为淘宝镜像源2. 设置为其他国内源三、还原为官方

最详细安装 PostgreSQL方法及常见问题解决

《最详细安装PostgreSQL方法及常见问题解决》:本文主要介绍最详细安装PostgreSQL方法及常见问题解决,介绍了在Windows系统上安装PostgreSQL及Linux系统上安装Po... 目录一、在 Windows 系统上安装 PostgreSQL1. 下载 PostgreSQL 安装包2.

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类

MySql match against工具详细用法

《MySqlmatchagainst工具详细用法》在MySQL中,MATCH……AGAINST是全文索引(Full-Textindex)的查询语法,它允许你对文本进行高效的全文搜素,支持自然语言搜... 目录一、全文索引的基本概念二、创建全文索引三、自然语言搜索四、布尔搜索五、相关性排序六、全文索引的限制七

python中各种常见文件的读写操作与类型转换详细指南

《python中各种常见文件的读写操作与类型转换详细指南》这篇文章主要为大家详细介绍了python中各种常见文件(txt,xls,csv,sql,二进制文件)的读写操作与类型转换,感兴趣的小伙伴可以跟... 目录1.文件txt读写标准用法1.1写入文件1.2读取文件2. 二进制文件读取3. 大文件读取3.1

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

如何在Mac上安装并配置JDK环境变量详细步骤

《如何在Mac上安装并配置JDK环境变量详细步骤》:本文主要介绍如何在Mac上安装并配置JDK环境变量详细步骤,包括下载JDK、安装JDK、配置环境变量、验证JDK配置以及可选地设置PowerSh... 目录步骤 1:下载JDK步骤 2:安装JDK步骤 3:配置环境变量1. 编辑~/.zshrc(对于zsh

SpringRetry重试机制之@Retryable注解与重试策略详解

《SpringRetry重试机制之@Retryable注解与重试策略详解》本文将详细介绍SpringRetry的重试机制,特别是@Retryable注解的使用及各种重试策略的配置,帮助开发者构建更加健... 目录引言一、SpringRetry基础知识二、启用SpringRetry三、@Retryable注解