JVM深入原理(五):JVM组成和JVM字节码文件

简介: 类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析。

JVM系列文章

  1. 深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器_eden used total max-CSDN博客
  2. JVM深入原理(一+二):JVM概述和JVM功能-CSDN博客
  3. JVM深入原理(三+四):JVM组成和JVM字节码文件-CSDN博客
  4. JVM深入原理(五):JVM组成和JVM字节码文件-CSDN博客
  5. JVM深入原理(六)(一):JVM类加载器-CSDN博客
  6. JVM深入原理(六)(二):双亲委派机制-CSDN博客
  7. JVM深入原理(七)(一):运行时数据区-CSDN博客
  8. JVM深入原理(七)(二):运行时数据区-CSDN博客
  9. JVM深入原理(八)(一):垃圾回收-CSDN博客
  10. JVM深入原理(八)(二):垃圾回收-CSDN博客

目录

5. JVM类的生命周期

5.1. 类的生命周期-概述

5.2. 类的生命周期-加载阶段

5.3. 类的生命周期-连接阶段

5.3.1. 连接阶段-验证阶段

5.3.2. 连接阶段-准备阶段

5.3.3. 连接阶段-解析阶段

5.4. 类的生命周期-初始化阶段

5.4.1. 初始化阶段-工作流程

5.4.2. 初始化阶段-触发情况

5.4.3. 初始化阶段-无clinit方法情况

5.4.4. 初始化阶段-父子类初始化情况

5.5. 类的生命周期-面试题

5.5.1. 1

5.5.2. 2


5. JVM类的生命周期

5.1. 类的生命周期-概述

  • 类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过
  • 类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析

    image.gif 编辑

5.2. 类的生命周期-加载阶段

  • 加载阶段的作用:加载字节码文件,给类分配内存空间
  • 加载阶段的步骤:
  1. 类加载器根据类的全限定名以二进制流方式将字节码文件加载到运行时数据区(字节码文件来源不同:本地文件,动态代理生成,网络传输)
  2. JVM将加载完毕的字节码信息保存到方法区中,JDK8保存在元空间中
  3. 方法区生成一个instanceKlass对象,其中保存了类所有的信息,还包含实现多态的信息等

    image.gif 编辑
  4. 同时堆中生成一个类似instanceKlass对象的java.lang.Class对象,通过Class对象反射获取类的信息以及存储静态字段的数据,这样就限制了开发者的访问范围

    image.gif 编辑

5.3. 类的生命周期-连接阶段

5.3.1. 连接阶段-验证阶段

  • 验证阶段的作用:JVM验证字节码文件的正确性,包括语法校验、语义校验、字节码验证等步骤。验证过程保证被加载的类是合法、符合规范的,没有安全方面的问题
  • 验证阶段验证部分:
  • 文件格式验证:比如文件是否以OxCAFEBABE开头,主次版本号是否满足当前JaVa虚拟机版本要求。

    image.gif 编辑
  • 元信息验证:例如类必须有父类
  • 验证程序执行指令的语义:比如方法内的指令执行到一半强行跳转到其他方法中去
  • 符号引用验证:例如是否访问了其他类中private的方法等

5.3.2. 连接阶段-准备阶段

  • 准备阶段的作用:JVM为被加载的类的静态变量分配内存,并设置默认初始值(用户指定的值赋值发生在初始化阶段),被final修饰的静态变量会在准备阶段直接赋值
  • 常见Java类型的初始值

    image.gif 编辑

5.3.3. 连接阶段-解析阶段

  • 解析阶段的作用:JVM将常量池内的符号引用转换为直接引用,以便于之后的访问和调用

5.4. 类的生命周期-初始化阶段

  • 初始化阶段的作用:JVM对类初始化,包括静态变量赋值,静态代码块执行等,同时保证初始化过程是线程安全的
  • 初始化阶段执行的字节码方法部分:初始化阶段会执行字节码文件中clinit部分的字节码指令

    image.gif 编辑

5.4.1. 初始化阶段-工作流程

  • 初始化阶段工作流程:字节码指令执行顺序跟Java代码编写顺序一致


  • image.gif 编辑
  1. iconst_1:将常量1压入栈中.
  2. putstatic#2:将栈中的数据弹出给常量池中的静态变量赋值
  3. iconst_2:将常量2压入栈中.
  4. putstatic#2:将栈中的数据弹出给常量池中的静态变量赋值

5.4.2. 初始化阶段-触发情况

  • 类初始化阶段被触发的情况:
  • 访问一个类不被final修饰的静态变量或静态方法
  • 调用Class.forName(String className)指定类
  • 使用new创建一个类的实例
  • 执行main方法的当前类
  • 访问一个类被final修饰但是需要执行指令才能得出结果的静态变量

    image.gif 编辑
  • --XX:+TraceClassLoading,打印已经初始化的类

5.4.3. 初始化阶段-无clinit方法情况

  • 类初始化阶段触发但没有clinit方法的情况:
  • 没有静态代码块和静态变量赋值语句
  • 有静态变量的声明,但没有复制语句
  • 有静态变量的声明,但用final关键字修饰(会在准备阶段赋值)
  • 创建该类的对象数组不会触发该类的初始化

    image.gif 编辑

5.4.4. 初始化阶段-父子类初始化情况

  • 子类不触发情况:直接访问父类的静态变量是不会触发子类初始化的
  • 父子都触发情况:子类的初始化clinit方法调用之前会先调用父类的clinit方法

5.5. 类的生命周期-面试题

5.5.1. 1

  • 这个程序执行的结果是什么?

    image.gif 编辑
  • 程序解题思路:
  1. 判断触发类的初始化情况:该类中执行main方法,所以该类会进行舒适化阶段
  2. 查看该类的字节码:字节码命令会告诉你代码块和构造方法的执行顺序
  • clinit字节码(初始化方法):在类的初始化时执行,初始化阶段执行静态代码块和给静态变量赋值

    image.gif 编辑
  • init字节码(构造方法):在类每次被创建实例时执行,执行代码块和构造方法,从字节码指令中可以看出,代码块打印C是先于构造方法打印B的

    image.gif 编辑
  • main字节码:由于该类调用main方法先进行初始化,在执行打印A,然后创建两次Demo实例,也就意味着调用两次代码块和构造方法

    image.gif 编辑
  • 最终的结果就是DACBCB

5.5.2. 2

  • 这个程序执行的结果是什么?

    image.gif 编辑
  • 程序解题思路:
  1. 调用B的clinit方法之前会先父类A的clinit方法
  2. a的值从0,到1,最后到2,最终打印结果也是2
  • 如果把new B()去掉它的执行结果是什么?

    image.gif 编辑
  • 程序解题思路:
  1. 直接访问B类的静态变量时不会进行子类的初始化
  2. 打印结果为1
目录
相关文章
|
30天前
|
Arthas 存储 算法
深入理解JVM,包含字节码文件,内存结构,垃圾回收,类的声明周期,类加载器
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行类的生命周期概述:类的生命周期描述了一个类加载,使用,卸载的整个过类的生命周期阶段:类的声明周期主要分为五个阶段:加载->连接->初始化->使用->卸载,其中连接中分为三个小阶段验证->准备->解析类加载器的定义:JVM提供类加载器给Java程序去获取类和接口字节码数据类加载器的作用:类加载器接受字节码文件。
201 55
|
30天前
|
Oracle Java 关系型数据库
JVM深入原理(一+二):JVM概述和JVM功能
JVM全称是Java Virtual Machine-Java虚拟机JVM作用:本质上是一个运行在计算机上的程序,职责是运行Java字节码文件,编译为机器码交由计算机运行。
56 0
|
30天前
|
Arthas 存储 Java
JVM深入原理(三+四):JVM组成和JVM字节码文件
目录3. JVM组成3.1. 组成-运行时数据区3.2. 组成-类加载器3.3. 组成-执行引擎3.4. 组成-本地接口4. JVM字节码文件4.1. 字节码文件-组成4.1.1. 组成-基础信息4.1.1.1. 基础信息-魔数4.1.1.2. 基础信息-主副版本号4.1.2. 组成-常量池4.1.3. 组成-方法4.1.3.1. 方法-工作流程4.1.4. 组成-字段4.1.5. 组成-属性4.2. 字节码文件-查看工具4.2.1. javap4.2.2. jclasslib4.2.3. 阿里Arthas
35 0
|
2月前
|
Arthas 监控 Java
Arthas memory(查看 JVM 内存信息)
Arthas memory(查看 JVM 内存信息)
118 6
|
5月前
|
存储 设计模式 监控
快速定位并优化CPU 与 JVM 内存性能瓶颈
本文介绍了 Java 应用常见的 CPU & JVM 内存热点原因及优化思路。
793 166
|
3月前
|
存储 缓存 算法
JVM简介—1.Java内存区域
本文详细介绍了Java虚拟机运行时数据区的各个方面,包括其定义、类型(如程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区和直接内存)及其作用。文中还探讨了各版本内存区域的变化、直接内存的使用、从线程角度分析Java内存区域、堆与栈的区别、对象创建步骤、对象内存布局及访问定位,并通过实例说明了常见内存溢出问题的原因和表现形式。这些内容帮助开发者深入理解Java内存管理机制,优化应用程序性能并解决潜在的内存问题。
219 29
JVM简介—1.Java内存区域
|
7月前
|
缓存 Prometheus 监控
Elasticsearch集群JVM调优设置合适的堆内存大小
Elasticsearch集群JVM调优设置合适的堆内存大小
1315 1
|
3月前
|
消息中间件 Java 应用服务中间件
JVM实战—2.JVM内存设置与对象分配流转
本文详细介绍了JVM内存管理的相关知识,包括:JVM内存划分原理、对象分配与流转、线上系统JVM内存设置、JVM参数优化、问题汇总。
108 12
JVM实战—2.JVM内存设置与对象分配流转
|
3月前
|
缓存 监控 算法
JVM简介—2.垃圾回收器和内存分配策略
本文介绍了Java垃圾回收机制的多个方面,包括垃圾回收概述、对象存活判断、引用类型介绍、垃圾收集算法、垃圾收集器设计、具体垃圾回收器详情、Stop The World现象、内存分配与回收策略、新生代配置演示、内存泄漏和溢出问题以及JDK提供的相关工具。
JVM简介—2.垃圾回收器和内存分配策略
|
3月前
|
存储 设计模式 监控
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?
如何快速定位并优化CPU 与 JVM 内存性能瓶颈?