Java 类加载机制
什么是类
类是现实世界的实体在计算中的映射、它将数据以及对这些数据的操作封装在一起。
类加载的定义
类加载是 JVM 运行时的一个动作、支持将 class 动态加载到 JVM 中
类加载是一种懒加载模式、按需加载。
类加载到五个过程
- 加载
- 验证
- 准备
- 解释
- 初始化
提一点,不要认为类加载是严格地前一阶段结束后一阶段开始,加载阶段尚未完成时,连接阶段(验证、准备、解析)可能已经开始了,但它们的开始时间是保持着固定的先后顺序的
加载
输入是 class 二进制流、加载到输出就是方法区的 InstanceKlass 对象以及堆中的 InstanceMirroKlass 对象
验证
确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机自身的安全
文件格式验证
字节流是否符合 Class 文件格式的规范
比如
- 是否以魔数0xCAFEABE开头
- 常量池中的常量中是否有不被支持的常量类型(检查常量tag标志)
- Class文件中各个部分及文件本身是否有被删除的或附加的其他信息
这阶段的验证是基于二进制字节流进行的,只有通过了这个阶段的验证后,字节流才会进入内存的方法区中进行存储,所以后面的3个验证阶段全部是基于方法区的存储结构进行的,不会再直接操作字节流
元数据验证
第二阶段是对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言规范的要求
- 这个类是否有父类(除了java.lang.Object以外,所有的类应当都有父类)
- 这个类的父类是否继承了不允许被继承的类(被final修饰的类)
- 如果这个类不是抽象类,是否实现了其父类或接口之中要求实现的所有方法
- 类中的字段、方法是否与父类产生矛盾(例如覆盖了父类的final字段,或者出现不符合规则的方法重载等)
字节码验证
第三阶段是整个验证过程中最复杂的一个阶段,主要目的是通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的
这一阶段是将对类的方法体进行校验分析,保证被校验类的方法在运行时不会做出危害虚拟机安全的事件
- 保证任意时刻操作数栈的数据类型与指令代码序列都能配合工作,比如不会出现这样的情况:在操作数栈放置了一个int类型的数据,使用时却按long类型来加载入本地变量表中
- 保证跳转指令不会跳转到方法体以外的字节码指令上
- 保证方法体中的类型转换是有效的,比如父类对象赋值给子类数据类型,甚至把对象赋值给与它毫无继承关系、完全不相干的一个数据类型,则是危险和不合法的
符号引用验证
最后一个阶段的校验发生在虚拟机将符号引用转化为直接引用的时候,这个转化动作将在连接的第三阶段————解析阶段中发生
符号引用验证可以看做是对类自身以外(常量池中的各种符号引用)的信息进行匹配性校验
- 符号引用中通过字符串描述的全限定名是否能找到对应的类
- 在指定类中是否存在符合方法的字段描述符以及简单名称所描述的方法和字段
- 符号引用中的类、字段、方法的访问性(private、protected、public、default)是否可被当前类访问
对于虚拟机的类加载机制来说,验证阶段时一个非常重要的阶段,但不是一定必要的。如果所运行代码都已经被反复使用和验证过,那么在实施阶段可以考虑使用 -Xverify:none 参数来关闭大部分的类验证措施,以缩短虚拟机类加载的时间
准备
准备阶段正式为静态变量(static修饰的)分配内存于堆区,并设置静态变量的零值(final修饰的除外)。这里不包括普通实例变量
在JDK7及之前,Hotspot使用的永久代来实现方法区时,静态变量(也成为类变量)是在方法区中分配的,而JDK8及以后,静态变量会随着Class对象一起移到Java堆中
static+final修饰的变量
static、final同时修饰的变量,不会赋零值,而会赋初值
在javac编译时会为变量生成ConstantValue属性,在准备阶段虚拟机会初始化为ConstantValue属性所指定的值
public static int v1 = 123;
public static final int v2 = 123;
在准备阶段结束后,v1是0,v2是123
为啥一定要在准备阶段去赋值 ? 如果我有一个 static int i 1 = 1
那它准备阶段做的初始化赋值 i = 0 有啥意义、它最终初始化阶段的结果都是 i = 1 ?
那如果该 static 变量没有赋值初值呢?那么它就不会在初始化阶段中被赋值、那么它就不会存在于 InstanceMirrorKlass 中、后续我们使用该变量会直接报错
解释
解释阶段是虚拟机将常量池内的符号应用替换为直接引用的过程
解释动作主要针对类或接口
- CONSTANT_Class_info
- CONSTANT_Class_info
- CONSTANT_Class_info
- CONSTANT_InterfaceMethodref_info
- CONSTANT_MethodType_info
- CONSTANT_MethodHandle_info
- CONSTANT_InvokeDynamic_info
解析动作具体来看
-
类或接口的解析。假设有一个类D,要把一个从未解析过的符号引用N解析为一个类或接口C的直接引用,分C是或不是数组类型来处理
- 如果C不是一个数组类型,那么虚拟机会把代表N的全限定名传递给D的类加载器,去加载这个类C(第1点)
- 如果C是一个数组类型,并且数组的元素类型为对象,也就是N的描述符会是类似“【Ljava/lang/Integer”的形式,那么将会按照(第1点)的规则加载数组元素类型,接着虚拟机会生成一个代表此数组维度和元素的数组对象
-
字段解析。需要对字段表内的class_index项中索引的CONSTANT_Class_info符号引用(字段所属的类或接口的符号引用)进行解析
-
类方法解析。需要对方法表的class_index项中索引的CONSTANT_Methodref_info符号引用(方法所属的类或接口的符号引用)进行解析
-
接口方法解析。需要对接口方法表的class_index项中索引的CONSTANT_InterfaceMethodref_info符号引用(方法所属的类或接口的符号引用)进行解析
符号引用转化为直接引用
符号引用(Symbolic References):符号引用以一组符号来描述所引用的目标,符号可以是任何形式的字面量,只要使用时能无歧义地定位到目标即可
运行之后、用 HSDB 分析
Constant Type = JVM_CONSTANT_Class 时,Constant Value = public class com.peter.jvm.example.SymbolicReferencesToDirectReferencesTest @0x00000007c0060828
初始化
初始化阶段是执行类构造器clinit方法的过程
clinit方法是由编译器自动收集类中所有静态变量的赋值动作和静态代码块中的语句合并产生的,编辑器收集的顺序是由语句在源文件中出现的顺序所决定的
clinit方法是什么
clinit方法是类构造器方法,编译器会收集所有静态变量的赋值动作、所有静态代码块,合并产生一个方法,即clinit,该方法在类加载中“初始化”阶段被调用
clinit方法的功能及特点
- clinit方法会执行静态代码块,给静态变量赋值
- clinit方法执行顺序由源文件中语句出现顺序决定
- 静态代码块中只能访问到定义在静态代码块之前的变量
- 静态代码块中可以给定义在它之后的变量赋值,但不能访问
public class Test {static {i = 0; // 给静态变量赋值可以正常编译通过System.out.print(i); // 定义在静态代码块之后的变量无法访问,会报编译错误}static int i = 1;
}
clinit 方法的必要性
clinit方法对于类或接口来说并不是必需的,如果一个类中没有静态代码块,也没有静态变量的赋值,编译器可以不为这个类生成clinit方法
在接口中执行 clinit 的逻辑
- 接口中不能使用静态代码块,但仍然有变量(默认是static、final的)初始化赋值的操作,因此接口与类一样都会生成clinit方法
- 接口与类不同的是,执行接口的clinit方法不需要先执行父接口的方法
- 只有当父接口中定义的变量使用时,父接口的clinit方法才会被执行
- 接口的实现类在执行clinit方法前也不需要先执行接口的clinit方法
多线程下执行clinit方法的逻辑
- 虚拟机会保证一个类的clinit方法再多线程环境中被正确的加锁、同步
- 如果多线程同时去初始化一个类,那么只会有一个线程去执行这个类的clinit方法,其他线程都需要阻塞等待,直到活动线程执行clinit方法完毕
- 如果一个类的clinit方法中有耗时很长的操作,就可能造成多个线程阻塞
这里亲身经历遇到过一个大坑、后面写一个文章记录下
类加载的时机
- 当虚拟机启动时,用户需要指定一个要执行的主类(包含main()方法的那个类),虚拟机会先初始化这个主类
- 遇到 new、getstatic、putstatic 或 invokestatic 这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化
- 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化
- 使用 java.lang.reflect 包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化·
- 档使用 JDK1.7 的动态语言支持时,如果一个 java.lang.invoke.MethodHandle 实例最后的解析结果 REF_getstatic、REF_putStatic、REF_invokeStatic 的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化
最后那一种忽略、没遇到过
注意:newarray,anewarray不会触发类加载
关于数组类
对于数组类而言,数组类本身不通过类加载器创建,它是由Java虚拟机直接创建的。但数组类与类加载器仍然有很密切的关系,因为数组类的元素类型(ElementType,指的是数组去掉所有维度的类型)最终是要靠类加载器去创建
创建过程遵循以下规则
- 如果数组的组件类型(Component Type,指的是数组去掉一个维度的类型)是引用类型,那就递归采用 自定义类加载器 => 应用程序类加载器 => 拓展类加载器 => 启动类加载器 的加载过程
- 如果数组的组件类型是基本类型(比如 int[]数组),就标记为与引导类加载器(我理解为启动类加载器)关联
数组本质也是一个类,注意不要与它的元素类搞混淆,比如B[] b = new B[100],B[]是数组类,B是元素类,而new一个数组对象时,是不会加载对应的元素类
public class ArraysTest {public static void main(String[] args) {A a = new A();B[] b = new B[100];}private static class A {static {System.out.println("A");}}private static class B {static {System.out.println("B");}}
}
输出结果为 A
B[] b = new B[100]; 只是初始化了一个数组对象,为该数组对象分配了内存,但没有为100个数组元素分配内存。假设B占1个字节,B[] b = new B[100]; 这句话会分配100个字节的内存,这样理解是不正确的。很显然new B[100]之后每个元素都是null,null是没有内存地址的,只有在数组元素初始化时才会去分配内存
这里最大的质疑问题是:加载一个数组,需要知道分配多少内存,分配内存就需要类加载,可为什么不需要加载元素类呢
在学完对象内存布局后,上面的质疑就可以清晰地回答了
数组也是一个类,叫数组类,它与普通类有区别,类加载过程不太一样
A[] a = new A[3]; 这句话,是对A[] 这个数组类加载了,没有对A这个元素类加载
加载A[] 这个数组类,是需要知道要分配多少内存的,这个肯定
就需要看一看数组对象 内部结构了,如下
- 对象头(包括MarkWord、类型指针、数组长度)
- 实例数据
- 对齐填充
关键在于实例数据,比如A[] a = new A[3]; 其中3个元素是分配在实例数据中的,而关键又在于分配的是什么
如果一个数组 int[] a = new int[3]; 这种情况下,实例数据占12个字节,因为int占4个,有3个int
如果一个数组 A[] a = new A[3]; 这种情况下,若开启指针压缩,实例数据占 12 个字节,若不开启指针压缩,实例数据占 24 个字节
这里有个概念,1个引用类型,开启指针压缩是4个字节,不开启是8个字节
然后可以看出来,对一个数组类分配内存的时候,其实是不需要知道元素类占多少内存的,数组对象中实例数据存储的是引用,也就是一个指向堆区对象的指针引用,它是4个字节或8个字节(是否开启指针压缩),只存储引用,不需要关心元素类占多少内存,也就不需要元素类的类加载了
关于常量池
- 静态常量池
- 运行时常量池
- 字符串常量池
相关文章:
Java 类加载机制
什么是类 类是现实世界的实体在计算中的映射、它将数据以及对这些数据的操作封装在一起。 类加载的定义 类加载是 JVM 运行时的一个动作、支持将 class 动态加载到 JVM 中 类加载是一种懒加载模式、按需加载。 类加载到五个过程 加载验证准备解释初始化 提一点࿰…...
Lombok是银弹?还是陷阱?
Lombok 是一个 Java 库,它通过注解简化和减少了 Java 中的样板代码(boilerplate code),例如 getter/setter 方法、构造函数、equals 和 hashCode 方法等。 对于是否将 Lombok 视为“银弹”或“陷阱”,这实际上取决于你…...
大数据技术-Hadoop(四)Yarn的介绍与使用
目录 一、Yarn 基本结构 1、Yarn基本结构 2、Yarn的工作机制 二、Yarn常用的命令 三、调度器 1、Capacity Scheduler(容量调度器) 1.1、特点 1.2、配置 1.2.1、yarn-site.xml 1.2.2、capacity-scheduler.xml 1.3、重启yarn、刷新队列 测试 向hi…...
CentOS修改docker镜像存储位置并进行数据迁移
在 CentOS 上修改 Docker 镜像存储位置并进行数据迁移是一个常见的需求。以下是一个详细的步骤指南,帮助你完成这个任务。 1. 停止 Docker 服务 首先,确保 Docker 服务已经停止,以避免在迁移过程中出现数据损坏。 sudo systemctl stop doc…...
xterm + vue3 + websocket 终端界面
xterm.js 下载插件 // xterm npm install --save xterm// xterm-addon-fit 使终端适应包含元素 npm install --save xterm-addon-fit// xterm-addon-attach 通过websocket附加到运行中的服务器进程 npm install --save xterm-addon-attach <template><div :…...
解锁 CSS:网页美化与布局的艺术
目录 一、CSS 是什么 二、CSS 的作用 三、CSS 的应用方式(引用方式) 四、选择器:如何挑选要 “打扮” 的元素 五、CSS 属性:丰富多样的 “服装款式” 字体属性: 文本属性:只能控制文字的相关样式。 …...
AWS K8s 部署架构
Amazon Web Services(AWS)提供了一种简化的Kubernetes(K8s)部署架构,使得在云环境中管理和扩展容器化应用变得更加容易。这个架构的核心是AWS EKS(Elastic Kubernetes Service),它是…...
【鸿蒙NEXT】鸿蒙里面类似iOS的Keychain——关键资产(@ohos.security.asset)实现设备唯一标识
前言 在iOS开发中Keychain 是一个非常安全的存储系统,用于保存敏感信息,如密码、证书、密钥等。与 NSUserDefaults 或文件系统不同,Keychain 提供了更高的安全性,因为它对数据进行了加密,并且只有经过授权的应用程序才…...
电子电器架构 --- HUD的工作原理
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源,以现象替代逻辑,以情绪代替思考,把消极接受现实的懦弱,伪装成乐观面对不幸的…...
C# 窗体应用程序嵌套web网页,基于谷歌浏览器内核(含源码)
有一个winform项目,需要借助一个web项目来显示,并且对web做一些操作,web页目是需要用谷歌内核,基于谷歌 Chromium项目的开源Web Browser控件来开发写了一个demo。 安装步骤 第一步:右键项目,点击 管理NuGet程序包 , 输…...
FFmpeg 中 examples 使用教程
FFmpeg 中 examples FFmpeg 的 examples 目录包含了一系列示例程序,旨在展示如何使用 FFmpeg 的不同库和 API。这些示例涵盖了多种功能,包括音视频编解码、格式转换、过滤、网络传输等。以下是一些常见的示例程序及其功能介绍: 音频和视频解码: 示例程序展示了如何打开音视…...
自动化办公-合并多个excel
在日常的办公自动化工作中,尤其是处理大量数据时,合并多个 Excel 表格是一个常见且繁琐的任务。幸运的是,借助 Python 语言中的强大库,我们可以轻松地自动化这个过程。本文将带你了解如何使用 Python 来合并多个 Excel 表格&#…...
Docker搭建MySQL
Docker搭建MySQL 准备工作 先准备配置目录和持久化目录,举个栗子:mkdir -p /opt/module/mysql/{conf,data,log}准备配置文件*.cnf,放到/opt/module/mysql/conf目录下。当然不准备也没事,容器中有个默认配置:/etc/mysql/conf.d/m…...
亚马逊国际站商品爬虫:Python实战指南
在数字化时代,数据的价值不言而喻。对于电商领域而言,获取竞争对手的商品信息、价格、评价等数据,对于市场分析和策略制定至关重要。本文将带你了解如何使用Python编写爬虫,以亚马逊国际站为例,按照关键字搜索并获取商…...
pwntools用法
pwntools 是一个Python库, 用于编写二进制漏洞利用(exploitation)脚本 功能: 远程连接和本地连接: 支持通过TCP/UDP连接远程服务或与本地进程进行交互。Shellcode和ROP链构造: 提供了便捷的工具来生成和利…...
企业云盘怎么选?2024年免费版9款整理
文章介绍了以下9大企业云盘:1.亿方云;2.Worktile;3.百度网盘;4.腾讯云盘;5.阿里云盘;6.金山云盘;7.Dropbox;8.Box。 在企业日常管理中,文件存储和共享一直是个不小的难题…...
Linux之ARM(MX6U)裸机篇----5.仿stm32的LED驱动实验
一,启动文件 .global _start .global _bss_start /* 类似宏定义把__bss_start定义为_bss_start */ _bss_start:.word __bss_start.global _bss_end _bss_end:.word __bss_end_start:#设置处理器进入SVC模式mrs r0, cpsr /* 读取cpsr到r0 */bic r0, r0, …...
Qt从入门到入土(七)-实现炫酷的登录注册界面(下)
前言 Qt从入门到入土(六)-实现炫酷的登录注册界面(上)主要讲了如何使用QSS样式表进行登录注册的界面设计,本篇文章将介绍如何对登录注册界面进行整体控件的布局,界面的切换以及实现登录、记住密码等功能。…...
如何进行年度工作回顾?
发生了什么事? 什么事情进展顺利 ? 什么事情进展不顺利? 如何适应未来? 年度回顾的定义:这是一种战略工具,能帮助人们清晰看到过去一年对业务、职业或个人生活的影响,可用于明确关键事件、找出问…...
spring默认线程池SimpleAsyncTaskExecutor特点为什么要尽量避免使用
在 Spring Boot 中,默认的线程池配置由 TaskExecutionAutoConfiguration 类提供,使用的是 SimpleAsyncTaskExecutor。 SimpleAsyncTaskExecutor特点 每次调用创建新线程: SimpleAsyncTaskExecutor 每次执行任务时都会创建一个新线程…...
每天40分玩转Django:Django表单集
Django表单集 一、知识要点概览表 类别知识点掌握程度要求基础概念FormSet、ModelFormSet深入理解内联表单集InlineFormSet、BaseInlineFormSet熟练应用表单集验证clean方法、验证规则熟练应用自定义配置extra、max_num、can_delete理解应用动态管理JavaScript动态添加/删除表…...
构建混合技术栈的统一监控与日志平台
文章目录 摘要引言构建统一监控与日志平台的核心思路痛点分析解决方案 平台架构设计架构概览 环境准备Java 服务的 Prometheus 指标导出Prometheus 指标采集模块Node.js 日志收集模块3. Logstash 配置4. Grafana 与 Kibana 配置 QA 环节总结未来展望参考资料 摘要 在多技术栈开…...
KOI技术-事件驱动编程(Sping后端)
1 “你日渐平庸,甘于平庸,将继续平庸。”——《以自己喜欢的方式过一生》 2. “总是有人要赢的,那为什么不能是我呢?”——科比布莱恩特 3. “你那么憎恨那些人,和他们斗了那么久,最终却要变得和他们一样,…...
ubuntu 20.04 国内源安装docker
先更新软件包,安装备要apt软件 # 更新软件包索引 sudo apt-get update# 安装需要的软件包以使apt能够通过HTTPS使用仓库 sudo apt-get install ca-certificates curl gnupg lsb-release使用阿里云源 # 添加阿里云官方GPG密钥 curl -fsSL http://mirrors.aliyun.co…...
微信小程序 app.json 配置文件解析与应用
目录 一、什么是 app.json? 二、app.json 文件的基本结构 三、详细解析 app.json 配置项 1. pages:小程序页面路径配置 2. window:窗口样式配置 3. tabBar:底部标签栏配置 4. networkTimeout:网络请求超时配置 …...
C高级:思维导图Day2
目录 总览1 总览2 总览1 压缩与解压缩 打包与解包 软连接与硬链接 ubuntu下关机与重启指令 总览2 结束...
蓝桥杯(Java)(ing)
Java前置知识 输入流: (在Java面向对象编程-CSDN博客里面有提过相关知识------IO流) // 快读快写 static BufferedReader in new BufferedReader(new InputStreamReader(System.in)); static BufferedWriter out new BufferedWriter(new…...
[Pro Git#2] 分支管理 | branch fix_bug , feature | 处理合并冲突
目录 一、Issue模板文件 二、Pull Requests模板文件 分支管理 1. 理解分支 2. 创建与管理分支 1. 切换分支与提交历史 2. 合并分支 3. 删除分支 4. 解决合并冲突 6. 查看分支合并情况 快速创建并切换分支 分支管理策略 分支合并模式 分支管理原则 日常开发环境 …...
Java——集合框架
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1 集合框架概述1.1 内存层面需要针对多个数据进行存储。此时,可以考虑的容器有:1.2 数组存储多个数据方面的特点和弊端1.3 Java集合框架体系…...
Mac 环境 VVenC 编译与编码命令行工具使用教程
VVenC VVenC 是一个开源的高效视频编码器,专门用于支持 H.266/VVC (Versatile Video Coding) 标准的编码。H.266/VVC 是继 HEVC (H.265) 之后的新一代视频编码标准,主要目的是提供比 HEVC 更高的压缩效率,同时保持或提高视频质量。H.266/VVC…...
WebRTC:实现浏览器与移动应用的实时通信
1.技术简介 (Web Real-Time)是一种开放式实时通信技术,旨在使浏览器和移动应用程序通过简单的API即可实现实时音频、视频和数据传输,而无需安装插件或额外软件。它支持网络应用中的点对点通信,例如视频聊天、语音通话…...
curl+openssl 踩坑笔记
curl编译:点击跳转 踩坑一 * SSL certificate problem: unable to get local issuer certificate * closing connection #0 curl: (60) SSL certificate problem: unable to get local issuer certificate More details here: https://curl.se/docs/sslcerts.html …...
【NebulaGraph】变化的多跳查询
【NebulaGraph】变化的多跳查询 1. 需求2. 解决方案2.1 确定查询结构2.2 构建查询语句 3. 追加需求:如果增加每一跳都要指定查询某SPACE下的Tag,或者不查询某个Tag怎么办 1. 需求 存在多跳请求,其中每一跳是从上一跳查询结果为基础的。但是 …...
【C++】九九乘法表编程题详解与多角度对比分析
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: C 文章目录 💯前言💯题目概述题目描述 💯老师的实现方法代码解析优点不足 💯我的实现方法代码解析优点不足 💯实现方法对比💯优化与扩展代码优化…...
node.js卸载并重新安装(超详细图文步骤)
卸载node.js 重新安装nodejs 一、卸载 1、首先进入控制面板卸载程序 2、卸载后 到文件夹中进行进一步的删除 删除上述的几个文件夹 每个人可能不一样,总之是找到自己的nodejs安装路径,下面是我的 ①删除C:UsersAdminAppDataRoaming路径下的npm相关文件…...
redis的集群模式与ELK基础
一、redis的集群模式 1.主从复制 (1)概述 主从模式:这是redis高可用的基础,哨兵和集群都是建立在此基础之上。 主从模式和数据库的主从模式是一样的,主负责写入,然后把写入的数据同步到从服务器ÿ…...
一份关于 Ubuntu 系统下代理配置的故障排查笔记
Ubuntu 网络代理配置与故障排查指南 在使用 Ubuntu 系统时,配置网络代理可以帮助提升网络访问速度或突破网络限制。然而,代理配置过程中可能会遇到各种问题。本文将详细介绍如何在 Ubuntu 下配置网络代理,并提供故障排查的步骤和解决方案。 …...
如何用jmeter工具进行性能测试
前言 今天我们来说说jmeter如何进行性能测试,我们都知道jmeter工具除了可以进行接口功能测试外,还可以进行性能测试。当项目趋于稳定,根据性能需求就可以着手准备性能测试了,今天就说一说jmeter如何进行性能测试,jmet…...
五、Vue 循环语句
文章目录 简介一、基础数组迭代二、对象属性迭代三、整数循环 简介 在 Vue.js 的世界里,当我们需要处理重复性的结构并依据数据动态渲染时,v-for 指令就成了不可或缺的工具,它赋予开发者简洁且强大的能力,轻松应对各种列表渲染场景…...
HMSC联合物种分布模型
联合物种分布模型(Joint Species Distribution Modelling,JSDM)在生态学领域,特别是群落生态学中发展最为迅速,Hmsc是物种群落分层模型的缩写(Hierarchical Modelling of Species Communities),它是一种基于…...
【CPU】risc-v指令集和其他指令集的差别(个人草稿)
第三,在 RISC-V 中对于所有指令,要读写的寄存器的标识符总是在同一位置,意味着在解码指令之前,就可以先开始访问寄存器。在许多其他的 ISA 中,某些指令字段在部分指令中被重用作为源目的地,在其他指令中又被…...
处理元素卡在视野边界,滚动到视野内
效果图如下: 本示例处理场景:点击底部的折叠面板,展开后移动端滚动条位置不变,导致展开内容在视图外。造成面板展开无内容的错觉。 处理核心API: IntersectionObserver 此API可绑定元素并监听元素是否在视野内。若在视野外…...
环,域,体,整区,理想,极大理想,
环: 定义: 加法交换群 乘法半群 分配律 域的定义: 加法交换群 乘法群(去掉0元是交换群) 分配律 Eg:比如整数集合不是域,因为对于乘法来说,去掉0后没有单位元了,但是是环 Eg…...
音视频入门基础:MPEG2-TS专题(22)——FFmpeg源码中,获取TS流的音频信息的实现
音视频入门基础:MPEG2-TS专题系列文章: 音视频入门基础:MPEG2-TS专题(1)——MPEG2-TS官方文档下载 音视频入门基础:MPEG2-TS专题(2)——使用FFmpeg命令生成ts文件 音视频入门基础…...
大模型—Ollama 结构化输出
Ollama 结构化输出 Ollama现在支持结构化输出,使得可以按照由JSON模式定义的特定格式来约束模型的输出。Ollama的Python和JavaScript库已经更新,以支持结构化输出。 结构化输出的用例包括: 从文档中解析数据从图像中提取数据结构化所有语言模型响应比JSON模式更可靠和一致开…...
基于Pytorch和yolov8n手搓安全帽目标检测的全过程
一.背景 还是之前的主题,使用开源软件为公司搭建安全管理平台,从视觉模型识别安全帽开始。主要参考学习了开源项目 https://github.com/jomarkow/Safety-Helmet-Detection,我是从运行、训练、标注倒过来学习的。由于工作原因,抽空…...
数据结构与算法基础(C语言版)
参考资料:https://www.bilibili.com/video/BV1GW421A7qY/ 所有代码均已在Ubuntu 20.04.6 LTS中测试通过 逻辑结构与存储结构 逻辑结构 逻辑结构指的是数据对象中数据元素间的相互关系,分为以下四种: 集合结构 集合结构中的数据元素除了同属于…...
Qt监控系统放大招/历经十几年迭代完善/多屏幕辅屏预览/多层级设备树/网络登录和回放
一、前言说明 近期对视频监控系统做了比较大的更新升级,主要就是三点,第一点就是增加了辅屏预览,这个也是好多个客户需要的功能,海康的iVMS-4200客户端就有这个功能,方便在多个屏幕打开不同的视频进行查看,…...
使用Locust对MySQL进行负载测试
1.安装环境 pip install locust mysql-connector-python 2.设置测试环境 打开MySQL服务 打开Navicat新建查询,输入SQL语句 3.编写locust脚本 load_mysql.py # codingutf-8 from locust import User, TaskSet, task, between import mysql.connector import ran…...
layui多图上传,tp8后端接收处理
环境:layui2.9.21\thinkphp8.1 前端代码: layui.use([upload, layer], function() {const upload layui.upload;const layer layui.layer;const $ layui.$;// 上传图片const uploadInstImage upload.render({elem: #uploadImage,url: /admin/demo/…...