中关村手机网站建设/海外品牌推广
文章目录
- Java对象内置结构
- 1.Java对象的三个部分
- 1.1.对象头
- 1.2.对象体
- 1.3.对齐字节
- 2.对象结构中核心字段的作用
- 2.1.MarkWord(标记字)
- 2.2.Class Pointer(类对象指针)
- 2.3.Array Length(数组长度)
- 2.4.对象体
- 2.5.对齐字节
- 3.Mark Word的结构信息
- 3.1.不同锁状态下的Mark Word字段结构
- 3.2.Mark Word的构成
- 4.使用JOL工具查看对象的布局
- 4.1.引入依赖
- 4.2.编写对象布局分析的测试代码
- 4.3.输出结果解读
- 4.4.大小端问题
- 5.Java中的内置锁
- 5.1.无锁状态
- 5.2.偏向锁状态
- 5.3.轻量级锁状态
- 5.4.重量级锁状态
Java对象内置结构
Java对象很多重要信息都存放在对象结构中,在学习Java内置锁之前,先来了解一下Java对象结构
1.Java对象的三个部分
1.1.对象头
对象头一共包括三个字段【Mark Word】【Class Pointer】【 Array Length】
- MarkWord(标记字),用于存储自身运行时的一些数据,例如GC标志位,哈希码,锁状态等信息。
- Class Pointer(类对象指针),用于存放此对象的元数据(InstanceKlass)的地址,虚拟机可以通过此指针确当这个对象是那个类的实例
- Array Length(数组长度),如果对象是一个Java数组,那么此字段必须有,用于记录数组长度的数据,如果不是数组,那么此字段不存在
1.2.对象体
对象体包含了,对象的实例变量(成员变量),用于成员属性值,包括父类的成员属性值,这部分内存按照4字节对齐
1.3.对齐字节
对齐字节(Alignment Byte)是为了优化内存访问效率而在Java中自动添加的额外字节。它确保对象和数组字段的对齐,提高内存访问的效率和性能。开发人员无需手动处理对齐字节,由Java虚拟机自动处理。
其中,对齐字节也称为填充对齐,作用就是用来保证Java对象在所占用内存字节数为8的倍数(8N Bytes),HotSopt VM内存管理要求,对象的起始地址必须是8字节的整数倍
2.对象结构中核心字段的作用
下面我们来对Object实例结构中的几个重要字段作一些简单说明
2.1.MarkWord(标记字)
在Java对象头部的一部分内存空间用于存储对象的元数据和状态信息,被称为MarkWord。MarkWord包含了对象的哈希码、锁信息、GC标记等信息。它的具体结构和内容在不同的JVM实现中可能会有所差异。
2.2.Class Pointer(类对象指针)
在Java对象头部的另一部分内存空间用于存储指向该对象所属类的指针,被称为Class Pointer。这个指针指向对象的类的元数据,包括类的方法、字段等信息。通过Class Pointer,可以在运行时获取对象所属的类,并进行相应的操作。
2.3.Array Length(数组长度)
对于数组对象,Java对象头部的一部分内存空间用于存储数组的长度信息。这个长度信息在创建数组时被初始化,之后无法被修改。
2.4.对象体
象体是Java对象的实际数据部分,包含了对象的字段值。对象体的大小取决于对象中定义的字段及其类型。对象体紧跟在对象头部之后,占据连续的内存空间。
2.5.对齐字节
在Java对象的内存布局中,为了对齐数据而添加的额外字节被称为对齐字节。对齐字节的存在是为了提高内存访问的效率和性能。它确保对象和数组字段的对齐,使得数据能够被高效地加载到寄存器或缓存中。
3.Mark Word的结构信息
Java内置锁涉及了很多的重要信息,这些都存放在对象结构中,放放于对象头的MarkWord字段中,MarkWord长度为JVM的一个Word大小,也就说32位JVM MakrWord 为32位 ,64位的Mark Word为64位,MarkWord的位长度并不会受到OOP对象指针压缩的影响。
Java内置锁的状态一共分为4种,【无锁】->【偏向锁】->【轻量级锁】->【重量级锁】,四种锁的状态会随着竞争的情况逐渐升级,而且过程是不可逆的(不可降级),锁只会升级,不会降级。
3.1.不同锁状态下的Mark Word字段结构
Mark Word 字段的结构和Java内置锁的结构 强相关,为了让Mark Word字段存储更多的信息,JVM将Mark Word的最低两个位置设置为Java内置锁状态
下面通过图来了解一下Mark Word 结构
3.2.Mark Word的构成
目前主流的JVM都是64位,使用64位的Mark Word 下面对64位的Mark Word的各部分进行简单介绍下
- **lock(锁状态):**lock字段用于表示对象的锁状态。它包含了对象的锁信息,可以标识对象是否被锁定,以及锁的类型(如无锁、偏向锁、轻量级锁、重量级锁等)。锁状态的具体取值和意义在不同的JVM实现中可能会有所差异。
- biased_lock(偏向锁标记):biased_lock字段用于表示对象是否启用了偏向锁。偏向锁是一种针对无竞争的情况下优化的锁机制,用于提高单线程访问同步块的性能。当对象启用偏向锁时,biased_lock字段的值为1,表示该对象已经偏向于某个线程,不需要进行锁的竞争。
- **age(对象年龄):**age字段用于表示对象的年龄。在垃圾回收的过程中,JVM会根据对象的年龄来决定是否将对象晋升为老年代。对象的年龄通过age字段进行记录,当对象经过一次Minor GC(年轻代垃圾回收)而没有被回收时,其年龄会增加。
- **identity_hashcode(标识哈希码):**identity_hashcode字段用于存储对象的标识哈希码。标识哈希码是对象的一个唯一标识,与对象的内容无关。它在需要比较对象的引用是否相等时起到重要的作用。
- **thread(持有锁的线程):**thread字段用于记录当前持有锁的线程。在多线程环境下,当一个线程获得对象的锁时,该字段会记录该线程的引用,以便在锁的释放或竞争时进行相应的操作。
- **epoch(锁记录的版本号):**epoch字段用于记录锁记录的版本号。它在偏向锁撤销和轻量级锁升级为重量级锁时起到重要作用。当锁状态发生变化时,会更新epoch字段的值,以确保锁记录的有效性。
- **ptr_to_lock_record(指向锁记录的指针):**ptr_to_lock_record字段用于指向对象的锁记录。锁记录是在竞争过程中创建的数据结构,用于记录锁的状态和竞争情况等信息。
- **ptr_to_heavyweight_monitor(指向重量级监视器的指针):**ptr_to_heavyweight_monitor字段用于指向重量级监视器的指针。当对象的锁升级为重量级锁时,会创建一个重量级监视器来管理锁的竞争。
这些字段在MarkWord中扮演着重要的角色,用于管理对象的锁状态、偏向锁、年龄、哈希码等信息。它们的具体含义和使用方式在不同的JVM实现中可能会有所不同,但它们都对对象的同步和垃圾回收起到了重要的作用。
4.使用JOL工具查看对象的布局
如何在Java程序中查看Object对象头的结构呢?我们可以使用OpenJDK提供的JOL工具
JOL是分析JVM中对象的结构布局的工具,该用具大量使用了Unsafe ,JVMTI来解码内部布局情况,分析结果还是比较准确的。
4.1.引入依赖
<!-- https://mvnrepository.com/artifact/org.openjdk.jol/jol-core -->
<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.10</version>
</dependency>
4.2.编写对象布局分析的测试代码
public class JOLTest {private static final Logger log = LoggerFactory.getLogger(JOLTest.class);@Test@DisplayName("测试JOL的使用")public void testJOL() {// 创建一个示例对象Student student = new Student();student.name = "喜羊羊";// 打印JVM信息log.error("JVM详细信息: {}", VM.current().details());// 打印对象布局信息log.error("对象布局:");log.error(ClassLayout.parseInstance(student).toPrintable());}}
class Student{public String name;
}
运行结果
4.3.输出结果解读
常见的Java数据类型及其在内存中所占用的字节数
数据类型 | 字节数 | 范围 | 备注 |
---|---|---|---|
boolean | 1 | true 或 false | 布尔类型只占用一个字节,但实际取值范围为 true 或 false。 |
byte | 1 | -128 到 127 | 有符号的8位整数类型。 |
short | 2 | -32,768 到 32,767 | 有符号的16位整数类型。 |
char | 2 | 0 到 65,535 | 无符号的16位Unicode字符类型。 |
int | 4 | -2,147,483,648 到 2,147,483,647 | 有符号的32位整数类型。 |
float | 4 | IEEE 754 单精度浮点数(有效位数约为 6-7 位) | 单精度浮点数类型,用于表示小数。 |
long | 8 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | 有符号的64位整数类型。 |
double | 8 | IEEE 754 双精度浮点数(有效位数约为 15 位) | 双精度浮点数类型,用于表示小数。 |
reference | 4 / 8 | 对象引用,取决于操作系统位数(32位操作系统为 4 字节,64位操作系统为 8 字节) | 表示对Java对象的引用,指向对象在堆中的内存地址。 |
对象头部(Object Header) | 12 | 对象的元数据和状态信息 | 对象头部包含标记字段、哈希码、锁信息等,具体结构和大小可能会因Java虚拟机实现的不同而有所差异。 |
需要注意的是,数据类型的字节数可能会因特定的编译器、操作系统和硬件架构而有所不同。引用类型的大小取决于操作系统的位数,32位操作系统上为4字节,64位操作系统上为8字节。对象头部(Object Header)的大小也可能因不同的Java虚拟机实现而有所不同。
通过结果我们可以得到
- 对象头部(object header)占据了前12个字节(0-11字节)的空间:
- 第一个字段(偏移量0):值为
01 00 00 00
,十六进制形式对应的二进制为00000001 00000000 00000000 00000000
。这是对象的标记字段,表示对象的状态和锁信息。 - 第二个字段(偏移量4):值为
00 00 00 00
,十六进制形式对应的二进制为00000000 00000000 00000000 00000000
。这个字段也是对象头部的一部分,具体含义可能是保留字段或其他元数据。 - 第三个字段(偏移量8):值为
80 77 13 01
,十六进制形式对应的二进制为10000000 01110111 00010011 00000001
。这个字段是对象头部的一部分,可能是用来存储对象的哈希码或其他标识信息。
- 第一个字段(偏移量0):值为
com.hrfan.java_se_base.base.thread.jol.Student
对象的实例大小为16字节。com.hrfan.java_se_base.base.thread.jol.Student
对象的字段中,只有一个字段是java.lang.String
类型的,即Student
对象的name
字段。该字段位于偏移量为12的位置,占据了4个字节的空间。- 对象的空间损失为0字节,既没有内部损失也没有外部损失。
4.4.大小端问题
有关字节序列存放格式,目前有两大主流阵营,一个阵营是PowerPC系列的CPU,采用大端模式进行存放数据,第二大阵营是X86系列的CPU采用小端模式存放数据
大小端(Endianness)是指在多字节数据类型存储时,字节的存放顺序。在计算机中,多字节数据类型(如整数、浮点数等)通常由多个字节组成,而字节本身是按照一定的顺序进行存储的。具体来说,大小端指的是最低有效字节(即最右边的字节)和最高有效字节(即最左边的字节)的存放顺序。
在大端字节序(Big Endian)中,最高有效字节存储在最低的地址,而最低有效字节存储在最高的地址。这意味着在多字节数据类型中,字节的存放顺序与它们的值相对应。例如,对于16位整数值0x1234,它的最高有效字节是0x12,最低有效字节是0x34,在大端字节序中,它们将按照如下顺序存储:0x12(高地址)和0x34(低地址)。
在小端字节序(Little Endian)中,最低有效字节存储在最低的地址,而最高有效字节存储在最高的地址。这意味着在多字节数据类型中,字节的存放顺序与它们的值相反。以同样的例子,对于16位整数值0x1234,在小端字节序中,它们将按照如下顺序存储:0x34(低地址)和0x12(高地址)。
内存地址 | 大端字节序 | 大端字节序(二进制) | 小端字节序 | 小端字节序(二进制) |
---|---|---|---|---|
0x1000 | 0x12 | 0001 0010 | 0x34 | 0011 0100 |
0x1001 | 0x34 | 0011 0100 | 0x12 | 0001 0010 |
在大端字节序中,高位字节(0x12)存储在低地址(0x1000),低位字节(0x34)存储在高地址(0x1001)。二进制表示为0001 0010(高位字节)和0011 0100(低位字节)。
在小端字节序中,低位字节(0x34)存储在低地址(0x1000),高位字节(0x12)存储在高地址(0x1001)。二进制表示为0011 0100(低位字节)和0001 0010(高位字节)。
5.Java中的内置锁
在JDK1.6之前,所有的锁都是重量级锁,重量级锁会造成CPU在用户态和核心态之间频繁切换,所以代价高效率地下。所以在JDK1.6以后,引入【偏向锁】,【轻量级锁】的实现。
当涉及到多线程并发访问共享资源时,Java中的锁状态会根据不同的情况进行动态调整。
5.1.无锁状态
无锁状态表示对象没有被任何线程锁定,多个线程可以同时访问该对象而不会发生互斥或同步等操作。这种情况通常在没有竞争的情况下发生。例如,以下代码片段展示了一个无锁状态的示例:
int counter = 0;// 线程1
counter++;// 线程2
counter++;
在这个示例中,两个线程可以同时对counter
变量进行递增操作,因为没有竞争发生。
5.2.偏向锁状态
偏向锁状态是一种针对无竞争情况下的优化。当一个线程获取了一个对象的锁,并且在之后连续多次访问该对象时,JVM会将该对象升级为偏向锁状态。偏向锁的目的是为了提高无竞争情况下的性能。以下是一个偏向锁状态的示例:
class Counter {private int count = 0;
}public class Test m {public static void main(String[] args) {Counter counter = new Counter();// 线程1获取锁并连续多次访问synchronized (counter) {counter.count++;counter.count++;// ...}// 线程2再次获取锁并访问synchronized (counter) {counter.count++;// ...}}
}
在这个示例中,线程1获取了counter
对象的锁,并连续多次访问了count
字段。由于没有其他线程竞争该锁,counter
对象会被升级为偏向锁状态,线程2再次获取锁时会直接进入偏向锁状态,从而避免了同步操作。
5.3.轻量级锁状态
轻量级锁状态适用于多个线程竞争同一个对象的锁的情况。在轻量级锁状态下,锁的获取和释放使用CAS操作来实现,避免了传统的互斥量机制,从而提高了性能。以下是一个轻量级锁状态的示例:
class Counter {private int count = 0;
}public class Test {public static void main(String[] args) {Counter counter = new Counter();// 线程1获取锁synchronized (counter) {// ...}// 线程2尝试获取锁synchronized (counter) {// ...}}
}
在这个示例中,线程1获取了counter
对象的锁,此时counter
对象处于轻量级锁状态。当线程2尝试获取锁时,它会使用CAS操作进行自旋尝试获取锁,如果竞争不激烈,线程2可以快速获取到锁,避免了进入重量级锁状态。
5.4.重量级锁状态
重量级锁状态适用于竞争激烈的情况,它使用操作系统的互斥量机制来进行锁的获取和释放。重量级锁确保了线程的互斥访问,但在竞争激烈的情况下可能导致线程的频繁切换和性能下降。以下是一个重量级锁状态的示例:
class Counter {private int count = 0;
}public class Test {public static void main(String[] args) {Counter counter = new Counter();while(true){// 线程1获取锁synchronized (counter) {// ...}// 线程2获取锁synchronized (counter) {// ...}// 特定条件下退出循环// .......}}
}
在这个示例中,线程1和线程2同时竞争获取counter
对象的锁。由于竞争激烈,JVM会将counter
对象升级为重量级锁状态,这时锁的获取和释放会涉及到操作系统的互斥量机制。
注意,具体的锁状态转换和升级过程由JVM自动管理,开发者在编写代码时无需显式处理锁状态的转换。锁状态的调整是根据实际的并发情况自动进行的。
后面我们会专门对偏向锁,轻量级锁,重量级锁进行分析
相关文章:

10.Java对象内置结构
文章目录 Java对象内置结构1.Java对象的三个部分1.1.对象头1.2.对象体1.3.对齐字节 2.对象结构中核心字段的作用2.1.MarkWord(标记字)2.2.Class Pointer(类对象指针)2.3.Array Length(数组长度)2.4.对象体2.5.对齐字节 3.Mark Word的结构信息3.1.不同锁状态下的Mark Word字段结…...

【ITK配准】第十五期 基于运动算法的可变形配准样例
很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享ITK配准中的基于运动算法的可变形配准,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 基于运…...

CSP-j 计算机硬件
计算机系统 计算机系统由计算机硬件和软件两部分组成。硬件包括中央处理器、存储器和外部设备等;软件是计算机的运行程序和相应的文档。计算机系统具有接收和存储信息、按程序快速计算和判断并输出处理结果等功能。 主要技术指标 字长:字长是指CPU能够同…...
Java中使用RediSearch进行高效数据检索
RediSearch是一款构建在Redis上的搜索引擎,它为Redis数据库提供了全文搜索、排序、过滤和聚合等高级查询功能。通过RediSearch,开发者能够在Redis中实现复杂的数据搜索需求,而无需依赖外部搜索引擎。本文将介绍如何在Java应用中集成并使用Red…...

NASA数据集——全球土壤顶部 1 厘米土壤湿度的网格估算值25km分辨率
AMSR-E/Aqua L2B Surface Soil Moisture, Ancillary Parms, & QC EASE-Grids V003 简介 该数据集包含土壤顶部 1 厘米土壤湿度的网格估算值,是 AMSR-E 检索足迹的平均值。土壤湿度是通过 AMSR-E/Aqua L2A亮度温度(Tb)测量值估算的&…...

翼支付——风控场景中图模型的范式变迁
目录 风控图深度学习模型 风控图大模型...

Edge视频增强功能
edge://flags/#edge-video-super-resolution 搜索Video查找 Microsoft Video Super Resolution 设置为Enabled...

C++ 概览并发
并发 资源管理 资源 程序中符合先获取后释放(显式或隐式)规律的东西,比如内存、锁、套接字、线程句柄和文件句柄等。RAII: (Resource Acquisition Is Initialization),也称为“资源获取就是初始化”,是C语言的一种管…...

04-19 周四 GitHub CI 方案设计
04-19 周四 GitHub CI 方案设计 时间版本修改人描述2024年4月19日14:44:23V0.1宋全恒新建文档2024年4月19日17:22:57V1.0宋全恒完成部署拓扑结构的绘制和文档撰写 简介 需求 由于团队最近把代码托管在GitHub上,为解决推理、应用的自动化CI的需要,调研了…...

java日常选择题
题目来自牛客网 1.以下哪个接口的定义是正确的?() A interface B { void print() {} ;} B interface B { static void print();} C.abstract interface B extends A1, A2 //A1、A2为已定义的接口 {abstract void print(){};} D.interface B { void print(); 选D,因…...

安卓串口通訊三
核心代碼如下: package com.example.comandroid;import static android.content.ContentValues.TAG;import android.graphics.Color; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.TextView;import…...

嵌入式交叉编译:Unable to find arm_neon.h
找到文件 搜索了一下,具体目录是: /opt/linux/x86-arm/aarch64-mix210-linux/lib/gcc/aarch64-linux-gnu/7.3.0/include/arm_neon.h 解决办法 INC_ARM/opt/linux/x86-arm/aarch64-mix210-linux/lib/gcc/aarch64-linux-gnu/7.3.0/include./configure …...

Linux下工具tc详细讲解及限制IP和端口实例
首先纠正某一篇博客,TC并不是只管发包不管收包,之前我也很纳闷 知道最后看到了14年前一位大佬的帖子。是ingress! 这里有个非常重要的点就是ingress,如果父类不是他的话是完不成限制源IP的,这个关键词表明你正在添加一个入口队列规…...

Java | Leetcode Java题解之第73题矩阵置零
题目: 题解: class Solution {public void setZeroes(int[][] matrix) {int m matrix.length, n matrix[0].length;boolean flagCol0 false;for (int i 0; i < m; i) {if (matrix[i][0] 0) {flagCol0 true;}for (int j 1; j < n; j) {if (…...

MySQL#MySql表的操作
目录 一、创建表 二、查看表结构 三、修改表 1.修改表的名字 2.新增一个列 3.修改列 4.删除列 5.修改列的名称 四、删除表 一、创建表 语法: CREATE TABLE table_name (field1 datatype,field2 datatype,field3 datatype ) character set 字符集 collate 校…...

git修改版本发布时间
一、场景 发现git版本发布时,服务器时间有误,需要修改。 二、解决 (1)准备 时间戳转换网址:http://shijianchuo.wiicha.com/ (2)SQLite 数据库 连接到安装git的服务器,修改版本表…...

【NodeMCU实时天气时钟温湿度项目 1】连接点亮SPI-TFT屏幕和UI布局设计
前言 从今天开始,我们详解介绍制作实时天气时钟项目的方法步骤,主要分以下几个专题分别进行:(1)连接点亮SPI-TFT屏幕和UI布局设计;(2)NodeMCU的WIFI模式设置及连接;&…...

国内首发 | CSA大中华区启动《AI安全产业图谱(2024)》调研
在人工智能(AI)技术的快速发展浪潮中,AI安全已成为全球关注的焦点。为应对AI安全带来的挑战,确保AI技术的健康发展,全球范围内的研究机构、企业和技术社区都在积极探索解决方案。 在这一背景下,CSA大中华区…...

web页面与原生android通信,调用原生android方法
注册初始化方法JsBridge //JS注册事件监听 function connectWebViewJavascriptBridge(callback) {if (window.WebViewJavascriptBridge) {callback(WebViewJavascriptBridge)} else {document.addEventListener(WebViewJavascriptBridgeReady,function() {callback(WebViewJav…...

Linux的编译器
程序编译的过程 程序的编译过程是将源代码转换为可执行文件的一系列步骤。这个过程涉及多个阶段,主要包括预处理、编译、汇编和链接。下面详细介绍每个阶段: 1. 预处理(Preprocessing) 在实际编译之前,源代码文件首…...

redis--安装
简介 官网:RedisInsight - The Best Redis GUI 各个版本官网下载地址:http://download.redis.io/releases/ Redis和Memcached是非关系型数据库也称为NoSQL数据库,MySQL、Mariadb、SQL Server、PostgreSQL Oracle 数据库属于关系型数据 应用…...

魔法程序员的奥妙指南:Java基本语法
作为一名魔法程序员,精通Java语言是至关重要的。Java作为一种强大的编程语言,在编写优质代码和开发强大应用程序时发挥着重要作用。让我们深入探讨Java基本语法的关键要点,从注释到变量,无所不包! Java基本语法的神秘魔…...

SpringMVC传递参数
1.RequestMapping RequestMapping本身可以处理,get或post,指定了get或post之后,就只能处理对应的请求。 RequestMapping(value{"haihiyo","goodMoring"},methodRequestMethod.POST)2.RestFul风格 RestFul是一种风格 比如:网站的访…...

【Scala---04】函数式编程 『 函数 vs 方法 | 函数至简原则 | 函数式编程』
文章目录 1. 函数 vs 方法1.1 方法(1) 定义方法(2) 运算符即方法 1.2 函数(1) 定义函数(2) 匿名函数 1.3 方法转为函数1.4 可变参数&默认参数 2. 函数至简原则3. 函数式编程3.1 函数式编程思想3.3 函数柯里化&闭包3.5 递归 & 尾递归 4. 补充4.1 访问元祖元素4.2 &g…...

[华为OD] B卷 树状结构查询 200
题目: 通常使用多行的节点、父节点表示一棵树,比如 西安 陕西 陕西 中国 江西 中国 中国 亚洲 泰国 亚洲 输入一个节点之后,请打印出来树中他的所有下层节点 输入描述 第一行输入行数,下面是多行数据,每行以空…...

基于机器学习的学生学习行为自主评价设计与实现
管理员功能: a)学生学习数据管理:可查看学生学习的详情,编辑学生学习的内容,删除和添加学生学习,设置学生学习库存。 b)角色管理:增加删除学生用户,分配学生用户权限,查看学生用户…...

toml与json联系对比
前言 本文简单介绍toml;并且和json转化做对比,以及我对toml设计的理解。 参考: TOML: 简体中文 v1.0.0 json和toml转化工具 在线JSON转toml-toml转JSON - bejson在线工具 正文 数组 说白了,就是一个变量名,有多个…...

(已解决)org.springframework.amqp.rabbit.support.ListenerExecutionFailedException
报错截图 解决方案 1、登录rabbitMQ网址,删除所有队列 2、重启rabbitMQ 亲测有效!!!亲测有效!!!亲测有效!!!...

基于FPGA的数字信号处理(9)--定点数据的两种溢出处理模式:饱和(Saturate)和绕回(Wrap)
1、前言 在逻辑设计中,为了保证运算结果的正确性,常常需要对结果的位宽进行扩展。比如2个3bits的无符号数相加,只有将结果设定为4bits,才能保证结果一定是正确的。不然,某些情况如77 14(1110),如果结果只…...

基于STM32的宠物箱温度湿度监控系统毕业设计
基于STM32的宠物箱温度湿度监控系统毕业设计 一、项目背景与意义 随着人们生活水平的提高,养宠物已经成为一种流行趋势。然而,对于宠物的居住环境,尤其是温度与湿度的控制,是确保宠物健康的关键。本项目旨在设计一款基于STM32微…...