JVM——Java对象的内存布局
Java对象的内存布局
在Java程序中,对象的内存布局是一个关键的底层概念。它不仅影响着对象的创建、使用和销毁的效率,也对垃圾回收、并发控制等机制有着深远的影响。下面我们将深入探讨Java对象的内存布局,包括对象的构成、内存分配、压缩指针、字段排列等,去更好地理解Java对象的内存管理机制。
Java对象的构成
在Java虚拟机(JVM)中,每个Java对象都有一个对象头,这个对象头由标记字段和类型指针所构成。其中:
-
标记字段 :用以存储Java虚拟机有关该对象的运行数据,如哈希码、GC分代年龄、锁信息等。
-
类型指针 :指向该对象的类元数据,JVM通过这个指针来确定对象的类型和类信息。
除了对象头,对象还包括实例字段和数组元素(对于数组对象)。这些部分共同构成了一个Java对象在内存中的完整布局。
public class ObjectLayoutExample {private int id;private String name;
public ObjectLayoutExample(int id, String name) {this.id = id;this.name = name;}
}
对象的内存分配
Java对象的内存分配主要通过堆内存进行。当使用new关键字创建对象时,JVM会为该对象在堆内存中分配相应的空间。内存分配的大小取决于对象头的大小、实例字段的大小以及内存对齐的填充等因素。
在64位的Java虚拟机中,对象头的标记字段和类型指针各占64位(即8字节),因此每个Java对象在内存中的额外开销为16字节。例如,一个仅包含一个int类型字段的类,其对象的内存开销将至少为16字节(对象头) + 4字节(int字段) + 填充(可能存在的内存对齐填充)。
压缩指针
为了减少对象的内存开销,64位Java虚拟机引入了压缩指针的概念(默认开启,可以通过虚拟机选项-XX:+UseCompressedOops来控制)。压缩指针将堆中原本64位的Java对象指针压缩成32位,从而减少了对象头的大小。
-
原理 :压缩指针通过对对象地址进行移位操作来实现地址的压缩和解压缩。例如,每辆房车占据两个停车位,我们通过将车位号除以2来得到车号,这样可以用32位的指针来表示原本需要64位的地址。
-
效果 :启用压缩指针后,对象头的大小从16字节降至12字节(标记字段仍为8字节,类型指针被压缩为4字节),从而显著降低了对象的内存开销。
在默认情况下,Java虚拟机堆中对象的起始地址需要对齐至8的倍数(通过虚拟机选项-XX:ObjectAlignmentInBytes设置)。如果对象的实际大小不是8的倍数,那么空白的那部分空间就被浪费掉,称为对象间的填充。
(一)压缩指针对性能的影响
-
优点 :通过压缩指针,可以显著减少堆内存的使用量,从而提高应用程序的性能,特别是在需要大量对象的应用程序中。较小的指针可以更容易地装入CPU的缓存中,加快内存访问的速度,这对于性能敏感的应用程序来说尤为重要。
-
缺点 :压缩指针可能导致更频繁的垃圾收集,因为堆内存使用量减少,JVM需要更频繁地进行垃圾回收以释放不再使用的对象,这可能会增加垃圾收集的开销,并且可能会对应用程序的响应速度产生影响。此外,由于压缩指针需要更多的计算来定位对象,因此内存分配的速度可能会稍微降低。在某些需要频繁分配内存的应用程序中可能是一个问题。压缩指针也可能与某些本地库或第三方库不兼容,由于压缩指针改变了指针的大小和布局,它可能与某些依赖于指针大小和布局的本地库或第三方库不兼容。这可能需要额外的调试和适配工作。
(二)压缩指针如何影响性能
压缩指针对Java应用程序的性能具有重要影响,主要体现在以下几个方面:
-
内存使用 :在64位JVM中,启用压缩指针可以显著减少堆内存的使用量,因为每个对象的引用从8字节减少到4字节。这对于堆内存大小不超过32GB的应用程序尤为重要,可以显著降低内存消耗,提高内存密集型应用的性能。
-
缓存利用率 :由于指针大小减小,CPU缓存可以容纳更多的对象引用,这有助于提高缓存命中率,减少内存访问次数,从而提高应用程序的响应速度和吞吐量。缓存命中率的提高对于性能敏感的应用程序尤为明显,因为缓存访问速度远快于主内存访问速度。
-
寻址效率 :压缩指针通过将64位指针压缩为32位,利用对象地址的对齐特性(通常是8字节对齐),通过简单的位移操作实现地址转换,这在大多数情况下可以快速完成,对性能的影响较小。然而,在某些需要频繁进行指针转换的场景下,可能会增加轻微的计算开销。
-
GC效率 :由于堆内存的使用量减少,垃圾回收(GC)的频率可能会降低,从而减少GC暂停时间,提高应用程序的整体性能。GC暂停时间的减少对于实时性要求较高的应用程序尤为重要,可以改善用户体验。
字段重排列
为了提高内存的利用率和访问效率,Java虚拟机会对对象的字段进行重排列,以满足内存对齐的要求。字段重排列遵循以下规则:
-
对齐规则 :如果一个字段占据C个字节,那么该字段的偏移量需要对齐至NC。例如,long字段(8字节)的偏移量需要对齐至8N。
-
继承字段位置 :子类所继承字段的偏移量,需要与父类对应字段的偏移量保持一致。Java虚拟机会对齐子类字段的起始位置,以确保父类和子类字段的正确布局。
class Parent {long parentLong;int parentInt;
}
class Child extends Parent {long childLong;int childInt;
}
(一)字段重排列对内存访问的影响
字段重排列对Java对象的内存访问性能具有重要影响,主要体现在以下几个方面:
-
缓存行利用率 :通过紧凑排列字段,可以减少缓存行的占用数量,从而提高缓存命中率。在Java对象的内存布局中,字段重排列可以确保对象的字段尽可能紧凑地排列在一个或多个缓存行中,减少内存访问的开销。例如,如果一个对象的字段能够完全填充一个缓存行,那么访问该对象时只需要加载一次缓存行,减少了内存访问的次数,提高了缓存命中率,从而提升程序的执行速度。
-
减少伪共享 :在多线程环境下,伪共享(False Sharing)问题可能导致多个线程频繁访问同一缓存行中的不同字段,导致缓存行的频繁写回,从而影响性能。通过字段重排列,将频繁访问的字段分散到不同的缓存行中,可以有效减少伪共享的发生。例如,Java 8引入的@Contended注解可以将不同的字段放置在独立的缓存行中,避免虚共享问题,提升多线程程序的性能。
-
内存对齐优化 :字段重排列可以确保字段的内存地址满足对齐要求,避免因未对齐访问而导致的性能损失。内存对齐可以确保CPU能够高效地读写数据,避免因数据未对齐而产生的额外开销,例如多次读写操作或硬件异常处理。在Java对象的内存布局中,字段重排列会根据字段的大小和类型进行对齐,以确保每个字段的起始地址符合其对齐要求,从而提高内存访问效率。
-
对象创建和GC效率 :紧凑的对象布局可以减少内存碎片,提高GC的效率。同时,对象创建时内存分配的速度也会因为布局优化而提升。优化后的对象内存布局可以减少内存分配过程中的碎片化问题,使得垃圾回收器能够更高效地回收和整理内存,降低GC的开销,提高程序的整体性能。
(二)内存对齐与填充
内存对齐是Java虚拟机为了提高内存访问效率而采取的一种策略。它要求某些数据类型(如long、double等)的起始地址必须是特定数值的倍数。如果字段不是对齐的,可能会导致跨缓存行的字段访问,从而降低程序的执行效率。
-
对象间填充 :由于对象的起始地址需要对齐至8的倍数,如果对象的实际大小不是8的倍数,那么在对象的末尾会添加填充字节,以满足内存对齐的要求。
-
字段间填充 :除了对象间的填充,Java虚拟机还会在对象的字段之间添加填充字节,以确保每个字段都满足内存对齐的要求。
(三)字段重排列对内存访问的影响
字段重排列可以显著提升Java对象的内存访问性能,主要体现在以下几个方面:
-
提高缓存行利用率 :通过将相关字段紧凑排列,确保对象的字段尽可能位于同一缓存行中,减少内存访问次数,提高缓存命中率,从而提升程序执行速度。
-
避免伪共享 :在多线程环境下,将不同线程频繁访问的字段分散到不同的缓存行中,可以有效减少伪共享问题,避免因缓存行的频繁写回而导致的性能瓶颈,提升并发程序的性能。
-
优化内存布局 :根据字段的大小和访问模式进行合理排列,可以减少对象的内存占用,提高内存的利用率,降低内存分配和垃圾回收的开销,从而提升程序的整体性能。
@Contended 注解与虚共享
Java 8引入了@Contended注解,用于解决对象字段之间的虚共享(false sharing)问题。虚共享是指多个线程分别访问同一对象中不同的字段,但由于这些字段位于同一个缓存行中,导致缓存行的频繁写回,从而影响性能。@Contended注解会将不同的字段放置在独立的缓存行中,避免虚共享问题。
public class ContendedExample {@Contendedprivate long field1;@Contendedprivate long field2;
}
(一)@Contended注解的使用场景
-
多线程高并发场景 :在多线程环境下,当多个线程频繁访问和修改同一对象的不同字段时,容易引发伪共享问题。此时,可以通过@Contended注解将这些字段分配到不同的缓存行中,避免缓存行的频繁争抢,提升程序的并发性能。
-
高性能计算场景 :对于需要进行大量计算和数据处理的高性能计算应用,数据的内存布局对性能有直接影响。通过合理使用@Contended注解,可以优化数据的缓存局部性,减少内存访问延迟,提高计算效率。
(二)@Contended注解的注意事项
-
性能开销 :虽然@Contended注解可以解决伪共享问题,但也会引入一定的性能开销。由于它会在字段之间添加额外的填充字节,增加了对象的内存占用,可能导致内存利用率下降。因此,在使用时需要权衡内存占用和性能提升之间的关系,避免过度使用而造成内存浪费。
-
编译器优化 :不同的Java编译器和虚拟机实现可能对@Contended注解的支持和优化程度不同。在某些情况下,编译器可能会忽略该注解,或者无法完全按照预期的方式进行字段排列和缓存行分配。因此,需要结合具体的Java版本和虚拟机配置进行测试和验证,确保注解的效果符合预期。
-
类和字段设计 :在设计类和字段时,需要综合考虑字段的访问模式和并发特性。对于不经常被并发访问的字段,可能不需要使用@Contended注解;而对于一些频繁被多个线程访问和修改的字段,合理使用该注解可以显著提升性能。因此,在类设计阶段就应该对字段的并发访问情况进行分析和评估,以便正确地应用@Contended注解。
实践与工具
为了更好地理解和分析Java对象的内存布局,可以使用JOL(Java Object Layout)工具。JOL可以帮助我们查看对象的内存布局、字段的偏移量和大小等信息。通过实践,我们可以更深入地了解Java对象的内存管理机制,从而优化程序的性能。
# 下载JOL工具
curl -L -O http://central.maven.org/maven2/org/openjdk/jol/jol-cli/0.9/jol-cli-0.9-full.jar
# 查看String类的内存布局
java -cp jol-cli-0.9-full.jar org.openjdk.jol.Main internals java.lang.String
(一)JOL工具的使用方法
-
查看对象的内存布局 :使用JOL工具,可以查看Java对象的内存布局,包括对象头、实例字段、数组元素以及填充字节等的详细信息。通过分析对象的内存布局,开发者可以了解对象的内存占用情况,找出潜在的内存浪费问题,从而进行针对性的优化。
-
分析字段的偏移量和大小 :JOL工具可以显示对象中各个字段的偏移量和大小,帮助开发者了解字段在内存中的排列顺序和对齐情况。根据这些信息,开发者可以调整字段的定义顺序,优化字段的排列,提高缓存行利用率,减少伪共享问题的发生。
-
评估内存对齐的影响 :通过观察对象和字段的内存对齐情况,开发者可以评估内存对齐对性能的影响。例如,如果发现某些字段存在大量的填充字节,可能表明内存对齐导致了内存浪费,此时可以考虑调整字段的大小或排列顺序,以减少填充字节的产生,提高内存利用率。
(二)JOL工具的实践案例
-
分析对象的内存占用 :通过JOL工具,我们可以准确测量Java对象的内存占用情况,包括对象头、实例字段和填充字节等所占的内存大小。这有助于我们了解不同对象的内存开销,优化对象的内存布局,减少内存浪费,提高程序的性能和可扩展性。
-
优化字段排列 :根据JOL工具提供的字段偏移量和大小信息,我们可以对字段的排列顺序进行优化。例如,将频繁一起访问的字段排列在一起,提高缓存行的利用率;将不同线程访问的字段分散到不同的缓存行中,避免伪共享问题。通过这些优化措施,可以显著提升程序的性能,尤其是在多线程环境下。
-
验证内存对齐效果 :使用JOL工具可以查看对象和字段的内存对齐情况,验证内存对齐是否达到预期的效果。如果发现内存对齐存在不合理之处,可以及时调整JVM的内存对齐参数或优化对象的内存布局,以确保内存对齐能够充分发挥其性能优势。
Java对象内存布局优化方法
(一)合理设计类的字段顺序
根据字段的大小和访问模式,合理排列字段的顺序可以减少内存浪费和提高缓存命中率。将频繁一起访问的字段排列在一起,将不同线程访问的字段分散到不同的缓存行中,可以根据字段的大小和对齐要求进行排列,以减少对象的内存占用。
(二)使用压缩指针
在64位JVM中,默认启用压缩指针可以显著减少堆内存的使用量,提高内存访问效率。当堆内存大小不超过32GB时,压缩指针可以有效地利用内存空间,提升程序的性能。
(三)避免伪共享
通过字段重排列或使用@Contended注解,确保不同线程访问的字段位于不同的缓存行中,避免伪共享问题。这可以显著提高多线程程序的性能,减少缓存行的争抢和写回开销。
(四)优化内存对齐
合理设置JVM的内存对齐参数,确保内存对齐能够提高缓存命中率,避免因未对齐访问而导致的性能损失。
(五)使用JOL工具进行分析和优化
利用JOL工具分析对象的内存布局,找出内存浪费和性能瓶颈,进行针对性的优化。通过实践和测试,不断调整和改进对象的内存布局,提升程序的性能。
总结
Java对象的内存布局是一个复杂而重要的主题。通过了解对象的构成、内存分配、压缩指针、字段重排列、内存对齐和填充等概念,我们可以更好地优化Java程序的性能,减少内存开销,并提高程序的并发性能。在实际开发中,合理地设计类的字段顺序、利用压缩指针和@Contended注解等技术手段,可以在一定程度上提升程序的效率和稳定性。
相关文章:
JVM——Java对象的内存布局
Java对象的内存布局 在Java程序中,对象的内存布局是一个关键的底层概念。它不仅影响着对象的创建、使用和销毁的效率,也对垃圾回收、并发控制等机制有着深远的影响。下面我们将深入探讨Java对象的内存布局,包括对象的构成、内存分配、压缩指…...
USB资料摘录for后期,bus hound使用
一、STM32F105 USB调试:专家级错误分析与调试技巧: 在实时操作系统(RTOS)中进行USB调试时,开发者需要考虑任务调度、中断优先级和资源共享等问题。STM32F105在支持RTOS的环境中调试USB,应重点分析USB驱动与RTOS内核之间的交互,以及如何避免可能的竞态条件。 在商业级应用…...
防止交叉验证中的数据泄露:提升模型在实际环境中的性能
防止交叉验证中的数据泄露:提升模型在实际环境中的性能 你刚刚完成了一个机器学习模型的训练,其验证准确率达到了95%。交叉验证结果显示性能稳定,项目相关方对此表示认可,正准备将模型部署到生产环境。但是现实情况却令人沮丧——…...
Debezium TableSchemaBuilder详解
Debezium TableSchemaBuilder详解 1. 类的作用与功能 1.1 核心作用 TableSchemaBuilder是Debezium中负责构建表Schema的核心类,主要功能包括: Schema构建:将数据库表结构转换为Kafka Connect的Schema定义主键处理:生成表的主键Schema值Schema处理:生成表的非主键字段Sc…...
25:三大分类器原理
1.分类的逻辑; 2.统计学与数据分析。 ************************ Mlp 多层感知系统 GMM 高斯混合模型-极大似然估计法 SVM 支持向量机建立一个超平面作为决策曲面,使得正例和反例的隔离边界最大化 Knn 1.MLP整个模型就是这样子的,上面…...
osquery在网络安全入侵场景中的应用实战(二)
背景 上次写了osquery在网络安全入侵场景中的应用实战(一)结果还不错,这次篇目二再增加一些场景。osquery主要解决的时员工被入侵之后电脑该如何溯源取证的问题。通常EDR会有日志,但是不会上报全量的日志。发现机器有恶意文件需要上级取证的时候,往往是比较麻烦的,会有这…...
排序用法(Arrays.sort)
排序范围: 对 res 数组中索引从 0到4 的行进行排序(因为结束索引5不包含)相当于排序 res[0] 到 res[4] 这5行 比较规则: o1 和 o2 是二维数组中的两行(如 [8,2] 和 [6,7])o1[0] - o2[…...
2025年最新Linux的Redis主从集群搭建
一:概述 Redis(Remote Dictionary Server)是一个开源的、高性能的键值存储系统,通常被用作数据库、缓存或消息中间件。它以内存存储为主,支持多种数据结构,并具备持久化、高可用、分布式等特性,…...
Oracle OCP认证考试考点详解083系列09
题记: 本系列主要讲解Oracle OCP认证考试考点(题目),适用于19C/21C,跟着学OCP考试必过。 41. 第41题: 题目 解析及答案: 关于应用程序容器,以下哪三项是正确的? A) 它可以包含单个…...
走出 Demo,走向现实:DeepSeek-VL 的多模态工程路线图
目录 一、引言:多模态模型的关键转折点 (一)当前 LMM 的三个关键挑战 1. 数据的真实性不足 2. 模型设计缺乏场景感知 3. 语言能力与视觉能力难以兼顾 (二)DeepSeek-VL 的根本出发点:以真实任务为锚点…...
Kotlin 作用域函数全解析:let、run、with、apply、also 应该怎么选?
Kotlin 提供了一套优雅的“作用域函数”(Scope Functions),包括:let、run、with、apply 和 also。它们看起来相似,行为上也有交集,但却各有侧重。掌握它们的使用场景,不仅能让代码更简洁&#x…...
Python 矩阵运算:从理论到实践
Python 矩阵运算:从理论到实践 在数据分析、机器学习以及科学计算等诸多领域,矩阵运算均扮演着极为重要的角色。借助 Python 的 NumPy 库,我们可以便捷地实现各类矩阵运算。本文将深入探讨矩阵运算的数学原理,并通过实例演示如何…...
系统架构-层次式架构设计
层次式体系结构是最通用的架构,大部分的应用会分成表现层(展示层)、中间层(业务层)、数据访问层(持久层)和数据层 表现层架构设计 使用XML设计表现层 使用UIP框架设计表现层,UIP将…...
《Python星球日记》第29天:Flask进阶
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏:《Python星球日记》,限时特价订阅中ing 目录 一、重温 Flask 框架二、路由与视图1. 动态路由2. 路由装饰器三、模板渲染1. Jinja2 模板语法2.…...
Baklib知识中台:智能服务架构新实践
智能服务架构四库体系 Baklib 知识中台的核心竞争力源于其独创的四库体系架构设计。该体系通过知识资源库、业务场景库、智能模型库和服务规则库的有机联动,构建起覆盖知识全生命周期的管理闭环。其中,知识资源库依托自然语言处理技术实现多源异构数据的…...
CBAM透视镜:穿透软件架构成本迷雾的评估范式
文章目录 一、引言二、CBAM 基础理论2.1 CBAM 的定义与概念2.2 CBAM 的核心原理2.2.1 成本效益分析的基本逻辑2.2.2 定量化决策过程 2.3 CBAM 与其他软件架构评估方法的比较2.3.1 与 ATAM 对比2.3.2 与 SAAM 对比 三、CBAM 在软件架构中的应用流程3.1 确定评估目标3.2 列出架构…...
macbook install chromedriver
# 打开 Chrome 访问以下地址查看版本 chrome://version/# 终端查看版本号 (示例输出: 125.0.6422.113) /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --version测试:...
Java 一战式学习指南,很详细
java基础 一、简介 1.1 JDK Java Develop Kit : Java的开发包,包含了Java的类库、执行Java所需的允许环境、各种开发辅助工具等... JDK 分为 Oracle JDK 和 Open JDK ,Oracle JDK需要商业许可证,是收费的。Open JDK 则是免费的。 1.2 Ja…...
从零开始开发纯血鸿蒙应用之NAPI
从零开始开发纯血鸿蒙应用 〇、前言一、解耦良器——Adapter二、详学 NAPI1、注册自定义的 NAPI1.1、Index.d.ts1.2、napi_property_descriptor 数组 2、读取参数2.1、读取字符类型数据2.1、读取数字类型 3、封装返回值4、C/C 调用 ArkTS 方法5、自定义 C 类的透传 三、总结坑点…...
立夏三候:蝼蝈鸣,蚯蚓出,王瓜生
今(5月5日)天是立夏节气,尽管本“人民+体验官”已是最畏惧感到气喘吁吁这夏天气候之老龄人,但还是要推广人民日报官方微博文化产品《文化中国行看立夏节气》。 人民微博着重提示“立夏三候”三个方面:“一候…...
Nuxt3还能用吗?
Nuxt3还能用吗? 前一段时间,我完成了整个产品,从Nuxt到Next的迁移,因为面临了一些在框架层面就无法解决的问题。 payload json化 在所有的的Nuxt中,我们都能看到有这样一个东西。 其实有这个东西也很正常࿰…...
专业课复习笔记 4
前言 实际上对于我的考研来说,最重要的两门就是数学和专业课。所以从今天开始,我尽可能多花时间学习数学和专业课。把里面的知识和逻辑关系理解清楚,把常考的内容练习透彻。就这样。 寻址方式 立即数寻址 操作数在指令里面直接提供了。 …...
[人机交互]交互设计
零.本章的主要目标 本章主要目标总结 区分良与非良交互设计,突出产品可用性差异阐述交互设计与HCI及其他领域的关系解释可用性概念概述交互设计过程涉及的内容概述交互设计中所使用的指南形式从可用性目标和原理角度,评估并解释产品的成败 一.什么是交…...
LeetCode 热题 100 17. 电话号码的字母组合
LeetCode 热题 100 | 17. 电话号码的字母组合 大家好,今天我们来解决一道经典的算法题——电话号码的字母组合。这道题在 LeetCode 上被标记为中等难度,要求给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。下面我将详细讲解解…...
【从零开始学习微服务 | 第一篇】单体项目到微服务拆分实践
目录 引言 一、选择聚合结构进行拆分的优势 二、微服务模块创建步骤 (一)引入 pom 文件与修改 (二)创建 Spring Boot 启动类 (三)搭建基本包结构 三、配置文件的引入与调整 四、业务代码的引入与注意…...
微前端qiankun动态路由权限设计与数据通信方案
思路: 权限控制中心化:主应用负责统一的管理权限,子路由上报路由信息 动态路由加载:根据用户权限动态注册可用路由 数据通信机制 主应用和子应用:通过qiankun提供的props和全局状态 子应用和子应用:通过…...
VTK 数据读取/写入类介绍
概述 VTK提供了多种数据读取和写入类,支持各种格式的输入输出操作,包括图像数据、多边形数据、结构化/非结构化网格数据等。 常用VTK读取类 vtkSTLReader 读取STL格式文件 属性: FileName - 要读取的STL文件名 方法: SetFileName(const char*) - 设置文件名 GetFileName…...
41.寻找缺失的第一个正数:原地哈希算法详解
文章目录 引言问题描述方法思路:原地哈希算法算法步骤 完整代码实现关键代码解析复杂度分析示例说明总结 引言 在算法面试和数据处理中,寻找缺失的第一个正数是一个经典问题。题目要求给定一个未排序的整数数组,找到其中缺失的最小正整数&am…...
项目实战-基于信号处理与SVM机器学习的声音情感识别系统
目录 一.背景描述 二.理论部分 三.程序设计 编程思路 流程图 1.信号部分 创建数据 generate_samples.py 头文件 生成函数 generate_emotion_sample 传入参数 存储路径 生成参数 创建基础正弦波信号 调制基础正弦波 对于愤怒可以增加噪声 归一化信号 存储 主函…...
基于Docker的MongoDB环境搭建:从零开始的完整实践指南
在现代应用开发中,容器化技术已成为构建可移植、易维护的服务环境的标准方案。MongoDB作为NoSQL数据库的代表,与Docker结合后能够显著提升部署效率。本文将深入解析如何通过Docker搭建安全可靠的MongoDB环境,涵盖基础配置、数据持久化、权限管理及安全加固等核心环节。 一、…...
C++ 类与对象(下)—— 进阶特性与底层机制解析(构造函数初始化,类型转换,static成员,友元,内部类,匿名对象)
一、构造函数初始化列表:给成员变量 “精准出生证明” 在 C 中,构造函数对成员变量的初始化方式有 初始化列表 和 函数体内赋值 两种。初始化列表是构造函数的一个重要特性,它允许在对象创建时对成员变量进行初始化。与在构造函数体内赋值不同…...
项目生成日志链路id,traceId
Trace 1. 注册filter package com.sc.account.config;import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;Configuration public cla…...
SQL常见误区
查询的顺序 书写顺序 SELECT 字段列表 FROM 表名列表 WHERE 条件列表 GROUP BY 分组字段列表 HAVING 分组后条件列表 ORDER BY 排序字段列表。。他们的加载顺序 逻辑处理实际顺序 常见错误 在 WHERE 中使用 SELECT 的别名 sql – 错误示例(WHERE 中不能使用别名…...
android zxing QrCode 库集成转竖屏适配问题
由于zxing 这个库使用比较广泛,所以大家也都遇到这个问题了,甚至最早可以追溯到十年前甚至更早,所以原创是谁已经无法找到,表明转载又需要填原文链接,就腆着脸标个原创了,不过的确不是我的原创,…...
实验4 mySQL查询和视图
一、实验目的 掌握SELECT语句的基本语法多表连接查询GROUP BY的使用方法。ORDER BY的使用方法。 二、实验步骤、内容、结果 实验内容: 实验4.1数据库的查询 目的与要求 (1)掌握SELECT语句的基本语法。 (2)掌握子查询的表示。 (3)掌握连接查询的表示。 (4)掌…...
解决用Deveco device tool无法连接local pc
原文链接:https://kashima19960.github.io/2025/05/05/openharmony/解决用Deveco%20device%20tool无法连接local%20pc/ 问题描述 WindowsUbuntu 环境下DevEco tool upload Hi3681开发 烧录 Local PC 箭头红一下,又绿了 用Deveco device tool进行upload…...
Google-chrome版本升级后sogou输入法不工作了
背景: 笔记本Thinkpad E450,操作系统Ubuntu 24.04.2 LTS,Chrome浏览器版本135.0.7049.114-1,Edge浏览器版本131.0.2903.99-1,输入法Sogou版本4.2.1.145 现象: - **正常场景**:Edge中可通过Ctrl…...
C++ 检查某个点是否存在于圆扇区内(Check whether a point exists in circle sector or not)
我们有一个以原点 (0, 0) 为中心的圆。作为输入,我们给出了圆扇区的起始角度和圆扇区的大小(以百分比表示)。 例子: 输入:半径 8 起始角 0 百分比 12 x 3 y 4 输出&am…...
电脑怎么分屏操作?
快捷键分屏 : 在打开两个窗口后,选中一个窗口,按下 “Windows 键 →” 键,该窗口会自动移动到屏幕右侧并占据一半空间,再点击需要分屏的窗口,即可完成分屏。若想恢复窗口为全屏,只需再次按下 …...
深度学习:智能助理从技术演进到全民普惠
在数字化浪潮席卷全球的今天,智能助理已成为人们生活与工作中不可或缺的伙伴。从简单的语音应答到如今具备复杂认知与交互能力,深度学习技术的持续突破,正推动智能助理行业迈向全新高度。深入探究其行业发展、现状、技术演进与实践࿰…...
哈希算法、搜索算法与二分查找算法在 C# 中的实现与应用
在计算机科学中,哈希算法、搜索算法和二分查找算法是三个非常基础且常用的概念。它们分别在数据存储、数据查找、以及高效检索等场景中起着至关重要的作用。在 C# 中,这些算法的实现和使用也十分简便。本文将详细讲解这三种算法的原理、应用以及 C# 中的…...
优化02-执行计划
Oracle 的执行计划(Execution Plan)是数据库优化器(Optimizer)为执行 SQL 语句而选择的操作路径和资源分配方案的详细描述。它记录了数据库如何访问表、索引、连接数据以及执行排序、过滤等操作的步骤。理解执行计划是性能调优的核…...
FreeRTOS菜鸟入门(十一)·信号量·二值、计数、递归以及互斥信号量的区别·优先级翻转以及继承机制详解
目录 1. 信号量的基本概念 2. 分类 2.1 二值信号量 2.2 计数信号量 2.3 互斥信号量 2.4 递归信号量 3. 应用场景 3.1 二值信号量 3.2 计数信号量 3.3 互斥信号量 3.4 递归信号量 4. 运作机制 4.1 二值信号量 4.2 计数信号量 4.3 互斥信号量 4.4…...
C++ -- 内存管理
C --内存管理 1. C/C内存分布2. C中动态内存管理3. C中动态内存管理4. 面对自定义类型5. operator new和operator delete6. new和delete的实现原理6.1 内置类型6.2 自定义类型 7. 定位new(placement new)7.1 底层机制7.2 本质 1. C/C内存分布 2. C中动态…...
基于muduo库实现高并发服务器
文章目录 一、项目介绍二、HTTP服务器1.概念2.Reactor模型2.1单Reactor单线程:单I/O多路复用业务处理2.2单Reactor多线程:单I/O多路复用线程池(业务处理)2.3多Reactor多线程:多I/O多路复用线程池(业务处理&…...
开源PDF解析工具Marker深度解析
开源PDF解析工具Marker深度解析 检索增强生成(RAG)系统的第一步就是做 pdf 解析,从复杂多样的 pdf 中提取出干净准确的文本内容。现有的最优秀的开源工具有两个:Marker 和 MinerU。因为 Marker 是个人开发者做的,文档…...
Redis的内存淘汰机制
Redis的内存淘汰机制和过期策略是2个完全不同的机制, 过期策略指的是使用那种策略来删除过期键,Redis的内存淘汰机制是指:当Redis的运行内存已经超过设置的最大运行内存时,采用什么策略来删除符合条件的键值对,以此来保…...
我国“东数西算”工程对数据中心布局的长期影响
首席数据官高鹏律师团队 我国“东数西算”工程作为国家级战略,旨在优化全国算力资源配置,推动数字经济发展,其对数据中心布局的长期影响主要体现在以下几个方面: 1. 区域协调与资源优化配置 东部与西部分工明确:东部…...
CPT204 Advanced Obejct-Oriented Programming 高级面向对象编程 Pt.10 二叉搜索树
文章目录 1.二叉树(Binary Trees)1.1 二叉搜索树(Binary Search Tree,简称BST)1.1.1 插入操作1.1.2 搜索操作1.1.3 树的遍历(Tree Traversal)1.1.3.1 前序遍历(Preorder Traversal&a…...
MinIO实现https访问
Windows下实现MinIO的https访问. 首先需要自己解决证书问题, 这里可以是个人证书 也可以是花钱买的证书. 现在使用个人开发者证书举例子。 将证书数据解压到你知道的目录之下 然后直接使用命令启动MinIO start minio.exe server --certs-dir D:\xxxxx\tools\certs …...