JVM学习总结:类的加载篇

news2024/11/6 12:41:22

本文是学习尚硅谷宋红康老师主讲的尚硅谷JVM精讲与GC调优教程的总结(文末有链接)

本篇可能被问到的问题:

  • 类的加载过程
  • 类加载器
    • 自定义类的加载器、ClassLoader
    • 双亲委派机制,破坏此机制的例子

类的加载过程(生命周期)

基本数据类型由虚拟机预先定义,引用数据类型则需要进行类的加载。

一个类只能被同 1 个类的加载器加载 1 次。

类的加载过程是前三个过程,生命周期多了后两个过程。

Loading (装载)阶段

  • 此阶段做的事

查找并加载类的二进制数据,生成 Class 的实例。

  • 加载的类在 JVM 中创建相应的类结构,类结构会存储在方法区(元空间)。

Class 实例存储在堆中。Class 类的构造方法是私有的,只有 JVM 能够创建。

  • 数组类的加载

数组类本身不是由类加载器负责创建,而是由 JVM 在运行时根据需要直接创建的,但数值的元素类型如果是引用类型的话需要依靠类加载器去创建。

Linking (链接)阶段

Verification (验证)

目的是保证加载的字节码是否合法、合理并符合规范的。(不用深究)

Preparation(准备)

为类的静态变量分配内存,并将其初始化为默认值。

假如有个类有如下静态变量:

private static int id = 1;

则在准备阶段只会把 id初始化为 int类型的默认值 0,在初始化阶段才会将其赋值为 1 。

有个例外是基本数据类型的字段用 static final 修饰的情况,准备阶段会显示赋值,因为 final 在编译的时候就会分配了。例如下面的 ID 会在准备阶段显示赋值为 1:

private static final int ID = 1

Resolution (解析)

将类、接口、字段和方法的符号引用转为直接引用,也就是得到类、字段、方法在内存中的指针或者偏移量。

符号引用是和内存没有关系的,是字节码文件中的引用,例如 info#24

直接引用是真实在内存中的引用。

解析操作往往会伴随着 JVM 在执行完初始化之后再执行。

Initialization (初始化)阶段

  • 此阶段做的事

为类的静态变量赋予正确的初始值(显示初始化)。

例如如下代码中将 id 赋值为 1 ,number 赋值为 2, C 赋值为 1000。

public class A {
    private static int id = 1;
    private static int number;
    private static final Integer C = Integer.valueOf(1000);

    static {
        number = 2;
    }
}

此阶段的重要工作是执行类的初始化方法:() 方法。static final 修饰的常量必须是调用方法赋值(不是常量),才会生成 () 方法。

  • 子类加载前先加载父类。由父及子,静态先行。

  • clinit的调用可能会调用死锁。

clinit是带锁线程安全的。

jps、jstack {pid} 查看

  • 类的加载时机

  • Class 的 forName(“Java.lang.String”) 和 Class 的 getClassLoader 的 loadClass(“Java.lang.String”) 有什么区别?

forName(“Java.lang.String”) 会执行装载、链接和初始化,loadClass 只会执行 装载。

  • 类的构造函数执行之前会先执行成员变量的显示赋值和构造块。

类的 Using (使用)

开发人员在程序中访问和调用类的静态成员信息(静态字段、静态方法),或者使用 new 关键字为其创建对象实例。

类的 Unloading (卸载)

一般只有自定义类加载器加载的类才会被卸载。

类的加载器

  • 类的加载器分为两类:

    • 引导类加载器 (Bootstrap ClassLoader),使用 C、C++ 语言编写。
    • 自定义类加载器 (User-defined Classloader),除了引导类加载器之外的,使用 Java 语言编写,继承抽象类 ClassLoader 类。
  • 图中常见类的加载器各自负责加载哪些类

    • Bootstrap ClassLoader:主要用来加载 JDK 内部的核心类库( %JAVA_HOME%/jre/lib目录下的 rt.jar 、resources.jar 、charsets.jar等 jar 包和类)以及被 -Xbootclasspath参数指定的路径下的所有类。
    • Extension ClassLoader:主要负责加载 %JRE_HOME%/jre/lib/ext 目录下的 jar 包和类以及被 java.ext.dirs 系统变量所指定的路径下的所有类。
    • Application ClassLoader:负责加载当前应用 classpath 下的所有 jar 包和类。
  • 图中的父类不是继承的关系,是通过组合实现的,成员变量 partent 指向上一级的加载器。

  • 让应用程序打印类加载信息:

    X:+TraceClassLoading 或者 -verbose:class
    
    java -XX:+TraceClassLoading Main
    
    java -verbose:class Main
    
  • 每个 Class 对象都会包含一个定义它的 ClassLoader 的一个引用,不过,数组类不是通过 ClassLoader 创建的,而是通过 JVM 在需要的时候自动创建的,数组类通过getClassLoader()方法获取 ClassLoader 的时候和该数组的元素类型的 ClassLoader 是一致的。

获取 ClassLoader 的途径:

- 获取当前类的 ClassLoader:clazz.getClassLoader()
- 获取当前线程上下文的 ClassLoader:Thread.currentThread().getContextClassLoader()
- 获取系统的 ClassLoader:ClassLoader.getSystemClassLoader()
- 获取当前 ClassLoader 的上层 ClassLoader:classLoader.getParent()

ClassLoader源码剖析

  • java.lang.ClassLoader
    • 方法 java.lang.ClassLoader#loadClass(java.lang.String, boolean)

体现了双亲委派机制

- 方法 java.lang.ClassLoader#findClass

根据类的二进制名称来查找类

- java.lang.ClassLoader#defineClass(java.lang.String, byte[], int, int)

将字节数组转换成 Class 实例,自定义类加载器时一般会调用这个方法

- java.lang.ClassLoader#preDefineClass

会对 java 开头的类进行保护,确保 JDK 核心 API 都是有 Bootstap ClassLoader 加载

  • sun.misc.Launcher.AppClassLoader

    应用程序类加载器,sun.misc.Launcher 的静态内部类
    
  • sun.misc.Launcher.ExtClassLoader

扩展类加载器,sun.misc.Launcher 的静态内部类

自定义类的加载器

实现方式

  • 继承 ClassLoader 类
  • 继承后有两种做法
    • 方式一:重写 loadClass() 方法 (打破双亲委派机制)
    • 方式二:重写 findClass() 方法 (遵循双亲委派机制,推荐)

相关机制

双亲委派机制

是什么

类加载器在进行类加载的时候,首先把请求委派给父类加载器去完成,这样所有的请求都会委派给最顶层的启动类加载器。

只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载。

优势
  • 避免类的重复加载,确保一个类的全局唯一性
  • 保护程序安全,防止核心 API 被随意篡改
劣势
  • 顶层的 ClassLoader 类无法访问底层的 ClassLoader 所加载的类,即系统类访问应用类会有问题。

解决方法:线程上下文类加载器 Thread.currentThread().getContextClassLoader()

破坏双亲委派机制的场景

Tomcat 类加载机制

Tomcat 服务器为了能够优先加载 Web 应用目录下的类,然后再加载其他目录下的类,就自定义了类加载器 WebAppClassLoader 来打破双亲委派机制。这也是 Tomcat 下 Web 应用之间的类实现隔离的具体原理。

Bootstrap
      |
    System
      |
    Common
     /  \
Server  Shared
         /  \
   Webapp1  Webapp2 ...

沙箱安全机制

JDK 9 中类加载结构的新变化

参考

  • 尚硅谷JVM精讲与GC调优教程(宋红康主讲,含jvm面试真题)
  • JavaGuide 公众号:携程一面:什么是双亲委派模型
  • Tomcat官方文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2230636.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS例子: 横向排列的格子

效果 HTML <view class"content"><view class"item" v-for"item of 5">{{item}}</view></view> CSS .content {height: 100vh;display: flex;flex-direction: row; flex-wrap: wrap;align-content: flex-start;backgro…

ElementUI el-form表单多层数组的校验

问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; ElementUI el-form表单多层数组的校验 页面效果&#xff1a; 数据结构&#xff1a; addform: {code: ,type: ,value: ,state: 1,remark: ,fieldList: [{fieldCode: ,resolverEntities: [{resolverType: , re…

房贷利率定价调整机制变更的一点理解

个人理解&#xff1a; 1、已知2024年第三季度全国新发放商业性个人住房贷款加权平均利率为3.33%。 而2024年7月、8月、9月的5年期以上LPR数据分别如下&#xff1a; - 7月20日调整后&#xff0c;5年期以上LPR为3.75%&#xff1b; - 8月的5年期以上LPR与7月相同&#xff0c;…

设计模式讲解01-建造者模式(Builder)

1. 概述 建造者模式也称为&#xff1a;生成器模式 定义&#xff1a;建造者模式是一种创建型设计模式&#xff0c;它允许你将创建复杂对象的步骤与表示方式相分离。 解释&#xff1a;建造者模式就是将复杂对象的创建过程拆分成多个简单对象的创建过程&#xff0c;并将这些简单…

[MySQL]DQL语句(一)

查询语句是数据库操作中最为重要的一系列语法。查询关键字有 select、where、group、having、order by、imit。其中imit是MySQL的方言&#xff0c;只在MySQL适用。 数据库查询又分单表查询和多表查询&#xff0c;这里讲一下单表查询。 基础查询 # 查询指定列 SELECT * FROM …

C/C++语言基础--C++模板与元编程系列三(变量模板、constexpr、萃取等…………)

本专栏目的 更新C/C的基础语法&#xff0c;包括C的一些新特性 前言 模板与元编程是C的重要特点&#xff0c;也是难点&#xff0c;本人预计将会更新10期左右进行讲解&#xff0c;这是第三期&#xff0c;讲变量模板、constexpr、萃取等知识&#xff1b;C语言后面也会继续更新知…

leetcode155:最小栈

设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初始化堆栈对象。void push(int val) 将元素val推入堆栈。void pop() 删除堆栈顶部的元素。int top() 获取堆栈顶部的元素。int get…

探秘机器学习算法:智慧背后的代码逻辑

1、 线性回归 线性回归是预测连续变量的一种简单而有效的方法。其数学模型假设因变量 y 与自变量 x 之间存在线性关系&#xff0c;用公式表示为&#xff1a; ​ Python代码实现 import numpy as np from sklearn.linear_model import LinearRegression import matplotlib.…

Spring中@Import和@ComponentScan注解差异

首先我们定义两个类 进行Component扫描 返回结果 进行Import导入 返回 结果 可以看 我们在对该类的所有bean加载没有任何问题 结果一致 但神奇的地方在于此时 我们把Tiger类头的Component注解去掉 ComponentScan注解无法识别Tiger中的Lion Bean 删掉Component 再进行ComonentS…

Ceph 学习指南 集群部署【 cephadm 】

文章目录 引言初识 Server SANServer SAN 和传统存储对比 Ceph 概述Ceph 的架构设计Ceph 的特点Ceph 块存储Ceph 文件系统Ceph 对象存储Ceph 介绍 Ceph 集群部署配置 aliyun 源配置时间同步配置 hosts 文件安装 docker配置免密登录ceph 集群部署ceph1 配置安装 python3安装 cep…

(JVM)在JVM中,类是如何被加载的呢?本篇文章就带你认识类加载的一套流程!

在讲类加载前&#xff0c;需要先了解一下方法区、堆和直接内存三块内存区域的运行模式 1. 方法区 JVM中的方法去是所有线程中共享的一块区域 它存储了跟类相关的信息 方法区 会在虚拟机被启动时创建。它逻辑上是堆的组成部分 它在不同的jvm厂商中存在的位置可能会不同&…

【Arduino】一分钟快速在vs code 编译开发Arduino

下载Arduino 对于一些开发者来说&#xff0c;Arduino开发较为不方便&#xff0c;不管从代码的阅读性、开发效率等等方面&#xff0c;vs code都要优于Arduino IDE开发&#xff0c;而且vs code开发可以使用插件&#xff0c;比如一些AI代码插件&#xff0c;可以加快开发速率&#…

qt QDialog详解

1、概述 QDialog是Qt框架中用于创建对话框的类&#xff0c;它继承自QWidget。QDialog提供了一个模态或非模态的对话框&#xff0c;用于与用户进行交互。模态对话框会阻塞其他窗口的输入&#xff0c;直到用户关闭该对话框&#xff1b;而非模态对话框则允许用户同时与多个窗口进…

去除windows系统桌面字体的黑影

然后点开设置&#xff0c;关闭以下的2个选项

ssm034学生请假系统+jsp(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;学生请假系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本学生请假系统就是在这…

如何利用8款工具辅助建立需求管理体系

本文中&#xff0c;分享了8款辅助建立需求管理体系的工具&#xff1a;1.PingCode&#xff1b;2.Worktile&#xff1b;3.Jira&#xff1b;4.Trello&#xff1b;5.ClickUp&#xff1b;6.Notion&#xff1b;7.蓝鲸智云&#xff1b;8.红橘。 在如今快速发展的商业环境中&#xff0c…

使用Flask构建RESTful API

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 使用Flask构建RESTful API Flask简介 环境搭建 安装Flask 项目结构 创建应用 路由定义 请求处理 获取查询参数 获取请求体 响应…

基于LLaMA Factory对LLama 3指令微调的操作学习笔记

一、环境 在vscode中用连接云服务器&#xff0c;打开文件目录。 df -h #查看盘容量 二、下载LLaMA Factory框架和数据 下载LLaMA Factory到云服务器 git clone https://github.com/hiyouga/LLaMA-Factory.git cd LLaMA-Factory pip install -e . pip install -e .命令的含…

解决VMwareWorkstation17中CentOS7不能上网的问题

在CentOS 7中查看网络状态&#xff0c;执行命令&#xff1a; systemctl status network.service 示例如下&#xff1a; [rootlinux ~]# systemctl status network.service 发现网络错误&#xff0c;解决办法&#xff1a; [rootlinux ~]# chkconfig NetworkManager off [rootli…

UI设计公司—兰亭妙微—提供轨道交通行业UI设计

蓝蓝设计工作室2008年开始&#xff0c;2011年正式成立北京兰亭妙微科技有限公司&#xff0c;主创清华团队&#xff0c;专注软件和互联网ui设计开发&#xff0c;擅长企业信息化管理、监控、大数据软件UIUE咨询和设计开发服务。立足UI&#xff0c;一直在学习进步。交通行业UE UI解…