当前位置: 首页 > news >正文

JVM故障处理与类加载全解析

1、故障处理工具

基础故障处理工具
jps:
可以列出正在运行的虚拟机进程,并显示虚拟机执行主类(Main Class,main()函数所在的类)名称以及这些进程的本地虚拟机唯一ID(LVMID,Local Virtual Machine Identifier)
jstat:
jstat(JVM Statistics Monitoring Tool)是用于监视虚拟机各种运行状态信息的命令行工具
jinfo:
jinfo(Configuration Info for Java)的作用是实时查看和调整虚拟机各项参数,windos使用该命令会受到限制
jmap:
jmap(Memory Map for Java)命令用于生成堆转储快照,jinfo命令一样,jmap有部分功能在Windows平台下是受限的
jhat:
JDK提供jhat(JVM Heap Analysis Tool)命令与jmap搭配使用,来分析jmap生成的堆转储快照。可以通过HTTP界面可视化
.java文件不可以直接被jhat分析我们需要先调用以下代码,转换文件格式
jstack:
jstack(Stack Trace for Java)命令用于生成虚拟机当前时刻的线程快照(一般称为threaddump或者javacore文件)。

2、类文件结构

class文件是一组以8个字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在文件之中,中间没有添加任何分隔符。
魔数和版本号
        Class文件的魔数是确定这个文件是否为一个能被虚拟机接收的Class文件——取值为0xCAFEBABE
        版本号分为主版本号和次版本号,高版本可以向下兼容低版本。虚拟机完全拒绝执行超过其版本号的Class文件
常量池
        常量池存储:字面量和符号引用。常量池的每一个常量都是一个表
访问标志
        这个标志用于识别一些类或接口层次的访问信息。
类索引、父类索引、接口索引集合
        class文件中有这三项数据来确定该类型的继承关系
字段表集合
        用于描述接口或类中声明的变量
方法表集合
属性表集合

3、类加载

类加载:JVM把类的数据从Class文件加载到内容,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型
类加载的时机
类的生命周期可以被定义为以下七个过程
加载——验证——准备——初始化——卸载顺序是确定的
有且仅有六种情况需要进行初始化(主动引用
  1. 遇到 new、getstatic、putstatic 或 invokestatic 这四条字节码指令时
  • 典型场景:使用 new 关键字实例化对象、读取或设置一个类的静态字段(被 final 修饰、已在编译期把结果放入常量池的静态字段除外)、调用一个类的静态方法
  1. 使用 java.lang.reflect 包的方法对类进行反射调用的时候
  2. 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化
  3. 当虚拟机启动时,用户需要指定一个要执行的主类(包含 main () 方法的那个类),虚拟机会先初始化这个主类
  4. 当使用 JDK 7 新加入的动态语言支持时
  5. 当一个接口中定义了 JDK 8 新加入的默认方法(被 default 关键字修饰的接口方法)时,如果有这个接口的实现类发生了初始化,该接口要在其之前被初始化
除此之外,所有引用类型的方式都不会触发初始化,称为被动引用。
给个例子
package org.fenixsoft.classloading;
/*** 被动使用类字段演示一:* 通过子类引用父类的静态字段,不会导致子类初始化**/
public class SuperClass {static {System.out.println("SuperClass init!");}public static int value = 123;
}
public class SubClass extends SuperClass {static {System.out.println("SubClass init!");}}
/*** 非主动使用类字段演示**/
public class NotInitialization {public static void main(String[] args) {System.out.println(SubClass.value);}
}
        上述代码运行之后,只会输出“SuperClass init!”,而不会输出“SubClass init!”。对于静态字段,只有直接定义这个字段的类才会被初始化,因此通过其子类来引用父类中定义的静态字段,只会触发父类的初始化而不会触发子类的初始化。
类的加载过程
加载、验证、准备、解析、初始化
加载过程
        通过类的全限定名获得字节流
        将字节流(静态)转换为方法区的运行时数据结构
        在内存生成该对象作为方法区这个类的访问接口
验证
        目的是确保Class文件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求。保证这些能正确地存储到方法区。
文件格式验证:保证输入的字节流能正确地解析并存储于方法区之内
元数据验证
字节码验证
符号引用验证
准备
只准备空间,这里的 初始值默认赋该类型的零值,若类变量被 final 修饰且为基本类型或字符串,则会在准备阶段初始化为指定值,静态常量直接赋值
解析
把符号引用直接转为直接引用的过程
初始化
把准备阶段赋的0值,转换为实际数据
使用
卸载
类加载器
        任意一个类,都必须由加载它的类加载器和这个类本身一起共同确立其在Java虚拟机中的唯一性,换句话说只有同一个类加载器加载出来的两个相同的类才相等。
类加载器分类
  • 启动类加载器Bootstrap ClassLoader:加载固定路径下,固定JRE/lib下的核心类库(如rt.jar)
  • 扩展类加载器Extension ClassLoader:加载JRE/lib/ext下的扩展类,是对Java语言的扩展
  • 应用程序类加载器Application ClassLoader:加载用户类路径(ClassPath)上的类
  • 自定义ClassLoader:用户自定义的类加载器
双亲委派模型
双亲委派
双亲委派模型的工作流程
        如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到最顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去完成加载
  • 类加载请求先委托父加载器处理
  • 父加载器无法完成时子加载器才尝试加载
优点:
  • 避免重复加载
  • 防止核心API被篡改
破坏双亲委派
破坏双亲委派,指的是类加载器在某些场景下不遵循 “先委托父类加载器” 的规则。例如:
Tomcat 的类加载器设计
        Tomcat 需要支持多个 Web 应用隔离(同一类在不同应用中可加载不同版本),因此其类加载器结构也破坏了双亲委派。
Tomcat 的类加载顺序(以 WebAppClassLoader 为例):
  1. 先加载 Web 应用的/WEB-INF/classes目录下的类;
  2. 再加载/WEB-INF/lib目录下的 JAR 包;
  3. 最后才委托父类加载器(Common ClassLoader)加载。
http://www.lryc.cn/news/584987.html

相关文章:

  • 数据结构自学Day5--链表知识总结
  • 大规模集群下 Prometheus 监控架构实战经验分享
  • LTR相关记录
  • 牛客周赛 Round 99
  • 【Dify(v1.x) 核心源码深入解析】mcp 模块
  • 4.丢出异常捕捉异常TryCatch C#例子
  • USB数据丢包真相:为什么log打印会导致高频USB数据丢包?
  • mysql数据库导入导出命令
  • 【Linux-云原生-笔记】系统引导修复(grub、bios、内核、系统初始化等)
  • Grok-4 发布会图文总结
  • 苹果UI 设计
  • SLICEGPT: COMPRESS LARGE LANGUAGE MODELSBY DELETING ROWS AND COLUMNS
  • Deepseek-如何从零开始开发需要专业知识的prompt
  • 8155平台SPI学习笔记
  • 从零实现一个GPT 【React + Express】--- 【4】实现文生图的功能
  • 深入剖析Spring Bean生命周期:从诞生到消亡的全过程
  • 英文国际期刊推荐:MEDS Chinese Medicine,中医药方向可发
  • 47-RK3588 用瑞芯微官方提供recovery进行OTA升级
  • Auto-GPT 简易教程
  • 前端抓包(不启动前端项目就能进行后端调试)--whistle
  • UI前端与数字孪生融合新领域:智慧环保的垃圾分类与回收系统
  • Windos服务器升级MySQL版本
  • 中国银联豪掷1亿采购海光C86架构服务器
  • 如何查看自己本地的公网IP地址?内网环境网络如何开通服务器公网ip提供互联网访问?
  • 电力分析仪的“双语对话”:CCLinkIE与Modbus TCP的无缝连接
  • 从《哪吒 2》看个人IP的破局之道|创客匠人
  • 【实用IP查询工具】IP数据云-IP地址查询离线库使用方案
  • 服务器机柜与网络机柜各自的优势
  • 解决Linux绑定失败地址已使用(端口被占用)的问题
  • python的卷烟营销数据统计分析系统