JVM常用调优参数 ——JVM篇

news2025/4/7 1:53:18

JVM常用性能调优参数详解

​ 在学习完整个JVM内容后,其实目标不仅是学习了解整个JVM的基础知识,而是为了进行JVM性能调优做准备,所以以下的内容就是来说说JVM性能调优的知识。

一、性能调优

​ 性能调优包含多个层次,比如:架构调优、代码调优、JVM调优、数据库调优、操作系统调优等等。

架构调优和代码调优是JVM调优的基础,其中架构调优是对系统影响最大的。

性能调优基本上按照以下步骤进行:

  • 明确优化目标
  • 发现性能瓶颈
  • 性能调优
  • 通过监控及数据统计工具获得数据
  • 确认是否达到目标

 二、何时进行JVM调优

遇到以下情况,就需要考虑进行JVM调优了:

  • Heap内存(老年代)持续上涨达到设置的最大内存值;
  • Full GC 次数频繁;
  • GC 停顿时间过长(超过1秒);
  • 应用出现OutOfMemory等内存异常;
  • 应用中有使用本地缓存且占用大量内存空间;
  • 系统吞吐量与响应性能不高或不降。

 

三、JVM调优的基本原则

​ JVM调优是一个手段,但并不一定所有问题都可以通过JVM进行调优解决;因此,在进行JVM调优时,我们要遵循一些原则

  • 大多数的Java应用不需要进行JVM优化;
  • 大多数导致GC问题的原因是代码层面的问题导致的(代码层面);
  • 上线之前,应先考虑将机器的JVM参数设置到最优;
  • 减少创建对象的数量(代码层面);
  • 减少使用全局变量和大对象(代码层面);
  • 优先架构调优和代码调优,JVM优化是不得已的手段(代码、架构层面);
  • 分析GC情况优化代码比优化JVM参数更好(代码层面)。
     

 通过以上原则,我们发现,其实最有效的优化手段是架构和代码层面的优化,而JVM优化则是最后不得已的手段,也可以说是对服务器配置的最后一次“压榨”。

四、JVM调优目标

 调优的最终目的都是为了令应用程序使用最小的硬件消耗来承载更大的吞吐。JVM调优主要是针对垃圾收集器的收集性能优化,令运行在虚拟机上的应用能够使用更少的内存以及延迟获取更大的吞吐量,总结以下:

  • 延迟:GC低停顿和GC低频率;
  • 低内存占用;
  • 高吞吐量。

 其中任何一个属性性能的提高,几乎都是以牺牲其他属性性能的损为代价的,不可兼得。具体根据在业务中的重要性确定。

五、JVM调优量化目标

 下面展示了一些JVM调优的量化目标参考实例:

  • Heap 内存使用率 <= 70%;
  • Old generation 内存使用率 <= 70%;
  • avgpause <= 1秒;
  • Full GC 次数 0 或 avg pause interval >= 24小时。

 六、JVM调优的步骤

一般情况下,JVM调优可通过以下步骤进行:

  • 分析GC日志及dump文件,判断是否需要优化,确定瓶颈问题点;
  • 确定JVM调优量化目标;
  • 确定JVM调优参数(根据历史JVM参数来调整);
  • 依次调优内存、延迟、吞吐量等指标;
  • 对比观察调优前后的差异;
  • 不断的分析和调整,直到找到合适的JVM参数配置;
  • 找到最合适的参数,将这些参数应用到所有服务器,并进行后续跟踪。
     

 以上操作步骤中,某些步骤是需要多次不断迭代完成的。一般是从满足程序的内存使用需求开始的,之后是时间延迟的要求,最后才是吞吐量的要求,要基于这个步骤来不断优化,每一个步骤都是进行下一步的基础,不可逆行之。

七、JVM参数

 JVM调优最重要的工具就是JVM参数。先来了解一下JVM参数相关内容。

​ -XX 参数被称为不稳定参数,**此类参数的设置很容易引起JVM性能上的差异,使 JVM 存在极大的不稳定性。**如果此类参数设置合理将大大提高JVM的性能及稳定性。

不稳定参数语法规则包含以下内容:

  • 布尔类型参数值:
    • -XX:+ ‘+’表示启用该选项
    • -XX:- ‘-’表示关闭该选项
  • 数字类型参数值:XX: = 给选项设置一个数字类型值,可跟随单位,例如:‘m’或‘M’表示兆字节;‘k’或‘K’千字节;‘g’或‘G’千兆字节。32K与32768是相同大小的。
  • 字符串类型参数值:-XX: = 给选项设置一个字符串类型值,通常用于指定一个文件、路径或一系列命令列表。例如:-XX:HeapDumpPath=./dump.core

 八、JVM参数解析及调优

 例如以下参数实例:

-Xmx4g 
–Xms4g 
–Xmn1200m 
–Xss512k 
-XX:NewRatio=4 
-XX:SurvivorRatio=8 
-XX:PermSize=100m 
-XX:MaxPermSize=256m 
-XX:MaxTenuringThreshold=15

 

 上面为Java7及以前版本的示例,**在Java8中永久代的参数-XX:PermSize和-XX:MaxPermSize已经失效。**这在前面章节中已经讲到。

参数解析:

  • -Xmx4g:堆内存最大值为4GB。
  • -Xms4g:初始化堆内存大小为4GB。
  • -Xmn1200m:**设置年轻代大小为1200MB。**增大年轻代后,将会减小年老代大小。此值对系统性能影响较大,Sun官方推荐配置为整个堆的3/8。
  • -Xss512k:**设置每个线程的堆栈大小。**JDK5.0以后每个线程堆栈大小为1MB,以前每个线程堆栈大小为256K。应根据应用线程所需内存大小进行调整。在相同物理内存下,减小这个值能生成更多的线程。但是操作系统对一个进程内的线程数还是有限制的,不能无限生成,经验值在3000~5000左右。
  • -XX:NewRatio=4:**设置年轻代(包括Eden和两个Survivor区)与年老代的比值(除去持久代)。**设置为4,则年轻代与年老代所占比值为1:4,年轻代占整个堆栈的1/5
  • -XX:SurvivorRatio=8:**设置年轻代中Eden区与Survivor区的大小比值。**设置为8,则两个Survivor区与一个Eden区的比值为2:8,一个Survivor区占整个年轻代的1/10
  • -XX:PermSize=100m:初始化永久代大小为100MB。
  • -XX:MaxPermSize=256m:设置持久代大小为256MB。
  • -XX:MaxTenuringThreshold=15:**设置垃圾最大年龄。**如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。

 

新生代、老生代、永久代的参数,如果不进行指定,虚拟机会自动选择合适的值,同时也会基于系统的开销自动调整。

可调优参数:

  • -Xms:初始化堆内存大小,默认为物理内存的1/64(小于1GB)。
  • -Xmx:**堆内存最大值。**默认(MaxHeapFreeRatio参数可以调整)空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。
  • -Xmn:新生代大小,包括Eden区与2个Survivor区。
  • -XX:SurvivorRatio=1:Eden区与一个Survivor区比值为1:1。
  • -XX:MaxDirectMemorySize=1G:**直接内存。**报java.lang.OutOfMemoryError: Direct buffer memory异常可以上调这个值。
  • -XX:+DisableExplicitGC:禁止运行期显式地调用System.gc()来触发fulll GC。
  • 注意: Java RMI的定时GC触发机制可通过配置-Dsun.rmi.dgc.server.gcInterval=86400来控制触发的时间。
  • -XX:CMSInitiatingOccupancyFraction=60:老年代内存回收阈值,默认值为68。
  • -XX:ConcGCThreads=4:CMS垃圾回收器并行线程线,推荐值为CPU核心数。
  • -XX:ParallelGCThreads=8:新生代并行收集器的线程数。
  • -XX:MaxTenuringThreshold=10:**设置垃圾最大年龄。**如果设置为0的话,则年轻代对象不经过Survivor区,直接进入年老代。对于年老代比较多的应用,可以提高效率。如果将此值设置为一个较大值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象再年轻代的存活时间,增加在年轻代即被回收的概论。
  • -XX:CMSFullGCsBeforeCompaction=4:指定进行多少次fullGC之后,进行tenured区 内存空间压缩。
  • -XX:CMSMaxAbortablePrecleanTime=500:当abortable-preclean预清理阶段执行达到这个时间时就会结束。

 ​ 注意:在设置的时候,如果关注性能开销的话,应尽量把永久代的初始值与最大值设置为同一值,因为永久代的大小调整需要进行FullGC才能实现。

九、内存优化示例

当JVM运行稳定之后,触发了FullGC我们一般会拿到如下信息:

image

​ 以上gc日志中,在发生fullGC之时,整个应用的堆占用以及GC时间。为了更加精确需多次收集,计算平均值。或者是采用耗时最长的一次FullGC来进行估算。上图中,老年代空间占用在93168kb(约93MB),以此定为老年代空间的活跃数据。则其他堆空间的分配,基于以下规则来进行。
 

  • java heap:参数-Xms和-Xmx,建议扩大至3-4倍FullGC后的老年代空间占用。
  • 永久代:-XX:PermSize和-XX:MaxPermSize,建议扩大至1.2-1.5倍FullGc后的永久代空间占用。
  • 新生代:-Xmn,建议扩大至1-1.5倍FullGC之后的老年代空间占用。
  • 老年代:2-3倍FullGC后的老年代空间占用。
     

 基于以上规则,则对参数定义如下:

-Xms373m -Xmx373m //4*93=372

-Xmn140m //1.5*93=139.5

-XX:PermSize=5m -XX:MaxPermSize=5m //1.5*3=4.5

 十、延迟优化示例

对延迟性优化,首先需要了解延迟性需求及可调优的指标有哪些。

  • 应用程序可接受的平均停滞时间: 此时间与测量的Minor
  • GC持续时间进行比较。可接受的Minor GC频率:Minor
  • GC的频率与可容忍的值进行比较。
  • 可接受的最大停顿时间:最大停顿时间与最差情况下FullGC的持续时间进行比较。
  • 可接受的最大停顿发生的频率:基本就是FullGC的频率。

 其中,**平均停滞时间和最大停顿时间,对用户体验最为重要。**对于上面的指标,相关数据采集包括:MinorGC的持续时间、统计MinorGC的次数、FullGC的最差持续时间、最差情况下,FullGC的频率。

image

 

如上图,Minor GC的平均持续时间0.069秒,MinorGC的频率为0.389秒一次。

​ **新生代空间越大,Minor GC的GC时间越长,频率越低。**如果想减少其持续时长,就需要减少其空间大小。如果想减小其频率,就需要加大其空间大小。

​ 这里以减少了新生代空间10%的大小,来减小延迟时间。在此过程中,应该保持老年代和持代的大小不变化。调优后的参数如下变化:

-Xms359m -Xmx359m 
-Xmn126m 
-XX:PermSize=5m -XX:MaxPermSize=5m

十一、吞吐量调优

 吞吐量调优主要是基于应用程序的吞吐量要求而来的,应用程序应该有一个综合的吞吐指标,这个指标基于整个应用的需求和测试而衍生出来的。

​ 评估当前吞吐量和目标差距是否巨大,如果在20%左右,可以修改参数,加大内存,再次从头调试,如果巨大就需要从整个应用层面来考虑,设计以及目标是否一致了,重新评估吞吐目标。

​ 对于垃圾收集器来说,提升吞吐量的性能调优的目标就是尽可能避免或者很少发生FullGC或者Stop-The-World压缩式垃圾收集(CMS),因为这两种方式都会造成应用程序吞吐降低。尽量在MinorGC 阶段回收更多的对象,避免对象提升过快到老年代。

十二、调优工具

 借助GCViewer日志分析工具,可以非常直观地分析出待调优点。可从以下几方面来分析:

  • Memory,分析Totalheap、Tenuredheap、Youngheap内存占用率及其他指标,理论上内存占用率越小越好;
  • Pause,分析Gc pause、Fullgc pause、Total pause三个大项中各指标,理论上GC次数越少越好,GC时长越小越好;

 

参考文献:

  • 从实际案例聊聊Java应用的GC优化-美团技术团队
  • JVM性能调优详解 (2019-11-11)
  • JVM参数使用手册

 

总结JVM参数使用手则

1. 内存相关

通过这些参数可以对JVM的内存分配做调整

  • Xms
    英文解释:Initial heap size(in bytes)
    中文释义:堆区初始值
    使用方法:-Xms2g 或 -XX:InitialHeapSize=2048m

  • Xmx
    英文解释:Maximum heap size(in bytes)
    中文释义:堆区最大值
    使用方法:-Xmx2g 或 -XX:MaxHeapSize=2048m

  • Xmn
    英文解释:Maximum new generation size(in bytes)
    中文释义:新生代最大值
    使用方法:-Xmn512m 或 -XX:MaxNewSize=512m

  • PermSize(JDK1.8以后已废弃)
    英文解释:Initial size of permanent generation(in bytes)
    中文释义:永久代初始大小
    使用方法:-XX:PermSize=128m

  • MaxPermSize(JDK1.8以后已废弃)
    英文解释:Maximum size of permanent generation(in bytes)
    中文释义:永久代最大值
    使用方法:-XX:MaxPermSize=256m

  • MetaspaceSize(JDK1.8以后用于替换PermSize)
    英文解释:Initial size of Metaspaces (in bytes)
    中文释义:元数据区初始大小
    使用方法:-XX:MetaspaceSize=128m

  • MaxMetaspaceSize(JDK1.8以后用于替换MaxPermSize)
    英文解释:Maximum size of Metaspaces (in bytes)
    中文释义:元数据区最大值
    使用方法:-XX:MaxMetaspaceSize=256m

  • Xss
    英文解释:Thread Stack Size(in Kbytes)
    中文释义:线程栈最大值
    使用方法:-Xss256k 或 -XX:ThreadStackSize=256k

  • MaxDirectMemorySize
    英文解释:Maximum total size of NIO direct-buffer allocations
    中文释义:最大直接内存(堆外)大小
    使用方法:-XX:MaxDirectMemorySize=256m

 2. GC策略相关

通过这些参数可以对JVM的GC性能进行调优

  • NewRatio

英文解释:Ratio of old/new generation sizes
中文释义:老年代和新生代的比值
使用方法:-XX:NewRatio=2
使用经验:假如设为2,则表示老年代最大内存占堆最大内存的2/3,新生代则为1/3。如果设置了Xmn或者NewSize/MaxNewSize,那么NewRatio配置无效

  • SurvivorRatio

英文解释:Rato of eden/survivor space size
中文释义:新生代中eden区和survivor区的比值
使用方法:-XX:SurvivorRatio=6
使用经验:假如设为6,则表示每个survivor区跟eden区的比值为1:6,每个survivor区占新生代的八分之一

  • PretenureSizeThreshold

英文解释:Maximum size in bytes of objects allocated in DefNew generation;zero means no maximum
中文释义:可以在新生代直接分配的对象最大值,0表示没有最大值
使用方法:-XX:PretenureSizeThreshold=1000000
使用经验:设置该参数,可以使大于这个值的对象直接在老年代分配,避免在Eden区和Survivor区发生大量的内存复制,该参数只对Serial和ParNew收集器有效,Parallel Scavenge并不认识该参数

  • MaxTenuringThreshold

英文解释:Maximum value fo tenuring threshold
中文释义:年轻代最大年龄
使用方法:-XX:MaxTenuringThreshold=10
使用经验:每个对象在坚持过一次Minor GC之后,年龄就增加1,当超过这个参数值时就进入老年代,最大支持15

  • UseSerialGC

英文解释:Use the Serial garbage collector
中文释义:年轻代使用Serial垃圾收集器
使用方法:
开启 -XX:+UseSerialGC
使用经验:不推荐使用,性能太差,老年代将会使用SerialOld垃圾收集器

  • UseParNewGC

英文解释:Use parallel threads in the new generation
中文释义:年轻代使用ParNew垃圾收集器
使用方法:
开启 -XX:+UseParNewGC

  • ParallelGCThreads

英文解释:Number of parallel threads parallel gc will use
中文释义:并行执行gc的线程数
使用方法:-XX:ParallelGCThreads=16

  • UseParallelGC

英文解释:Use the Parallel Scavenge garbage collector
中文释义:年轻代使用Parallel Scavenge垃圾收集器
使用方法:
开启 -XX:+UseParallelGC
使用经验:Linux下1.6,1.7,1.8默认开启,老年代将会使用SerialOld垃圾收集器

  • UseParallelOldGC

英文解释:Use the Parallel Old garbage collector
中文释义:年轻代使用Parallel Scavenge收集器
使用方法:
开启 -XX:+UseParallelOldGC
使用经验:老年代将会使用Parallel Old收集器

  • UseConcMarkSweepGC

英文解释:Use Concurrent Mark-Sweep GC in the old generation
中文释义:老年代使用CMS收集器(如果出现"Concurrent Mode Failure",会使用SerialOld收集器)
使用方法:
开启 -XX:+UseConcMarkSweepGC
使用经验:年轻代将会使用ParNew收集器

  • CMSInitiatingOccupancyFraction

英文解释:Percentage CMS generation occupancy to start a CMS collection cycle. A negative value means that CMSTriggerRatio is used
中文释义:触发执行CMS回收的当前年代区内存占用的百分比,负值表示使用CMSTriggerRatio设置的值
使用方法:-XX:CMSInitiatingOccupancyFraction=75
使用经验:该参数需配合UseCMSInitiatingOccupancyOnly一起使用

  • UseCMSInitiatingOccupancyOnly

英文解释:Only use occupancy as a criterion for staring a CMS collection
中文释义:只根据占用情况作为开始执行CMS收集的标准,默认关闭
使用方法:
开启 -XX:+UseCMSInitiatingOccupancyOnly

  • UseCMSCompactAtFullCollection

英文解释:Use Mark-Sweep-Compact algorithm at full collections
中文释义:使用CMS执行Full GC时对内存进行压缩,默认关闭
使用方法:
开启 -XX:+UseCMSCompactAtFullCollection

  • CMSFullGCsBeforeCompaction

英文解释:Number of CMS full collection done before compaction if > 0
中文释义:多少次FGC后进行内存压缩
使用方法:-XX:CMSFullGCsBeforeCompaction=1

  • CMSClassUnloadingEnabled

英文解释:Whether class unloading enabled when using CMS GC
中文释义:当使用CMS GC时是否启用类卸载功能,默认关闭
使用方法:
开启 -XX:+CMSClassUnloadingEnabled

  • CMSParallelRemarkEnabled

英文解释:Whether parallel remark enabled (only if ParNewGC)
中文释义:是否启用并行标记(仅限于ParNewGC),默认关闭
使用方法:
开启 -XX:+CMSParallelRemarkEnabled

  • UseG1GC

英文解释:Use the Garbage-First garbage collector
中文释义:使用G1垃圾收集器
使用方法:
开启 -XX:+UseG1GC

  • MaxGCPauseMillis

英文解释:Adaptive size policy maximum GC pause time goal in millisecond, or (G1 Only) the maximum GC time per MMU time slice
中文释义:自适应大小策略的最大GC暂停时间目标(以毫秒为单位),或(仅G1)每个MMU时间片的最大GC时间
使用方法:-XX:MaxGCPauseMillis=200

  • DisableExplicitGC

英文解释:Ignore calls to System.gc()
中文释义:禁用System.gc()触发FullGC
使用方法:
开启 -XX:+DisableExplicitGC
PS:不建议开启,如果开启了这个参数可能会导致堆外内存无法及时回收造成内存溢出

 

3. GC日志相关

通过这些参数可以对JVM的GC日志输出进行配置,方便分析

  • Xloggc

英文解释:GC log file
中文释义:GC日志文件路径
使用方法:-Xloggc:/data/gclog/gc.log

  • UseGCLogFileRotation

英文解释:Rotate gclog files(for long running applications). It requires -Xloggc:<filename>
中文释义:滚动GC日志文件,须配置Xloggc
使用方法:
开启 -XX:+UseGCLogFileRotation

  • NumberOfGCLogFiles

英文解释:Number of gclog files in rotation(default:0,no rotation)
中文释义:滚动GC日志文件数,默认0,不滚动
使用方法:-XX:NumberOfGCLogFiles=4

  • GCLogFileSize

英文解释:GC log file size,requires UseGCLogFileRotation. Set to 0 to only trigger rotation via jcmd
中文释义:GC文件滚动大小,需配置UseGCLogFileRotation,设置为0表示仅通过jcmd命令触发
使用方法:-XX:GCLogFileSize=100k

  • PrintGCDetails

英文解释:Print more details at garbage collection
中文释义:GC时打印更多详细信息,默认关闭
使用方法:
开启 -XX:+PrintGCDetails
可以通过jinfo -flag [+|-]PrintGCDetails <pid> 或 jinfo -flag PrintGCDetails=<value> <pid> 来动态开启或设置值

  • PrintGCDateStamps

英文解释:Print date stamps at garbage collection
中文释义:GC时打印时间戳信息,默认关闭
使用方法:
开启 -XX:+PrintGCDateStamps
可以通过jinfo -flag [+|-]PrintGCDateStamps <pid> 或 jinfo -flag PrintGCDateStamps=<value> <pid> 来动态开启或设置值

  • PrintTenuringDistribution

英文解释:Print tenuring age information
中文释义:打印存活实例年龄信息,默认关闭
使用方法:
开启 -XX:+PrintTenuringDistribution

  • PrintGCApplicationStoppedTime

英文解释:Print the time of application has been stopped
中文释义:打印应用暂停时间,默认关闭
使用方法:
开启 -XX:+PrintGCApplicationStoppedTime

  • PrintHeapAtGC

英文解释:Print heap layout before and after each GC
中文释义:GC前后打印堆区使用信息,默认关闭
使用方法:
开启 -XX:+PrintHeapAtGC

 

4. 异常相关

通过这些参数可以在JVM异常情况下执行某些操作,以保留现场做分析用

  • HeapDumpOnOutOfMemoryError

英文解释:Dump heap to file when java.lang.OutOfMemoryError is thrown
中文释义:抛出内存溢出错误时导出堆信息到指定文件,默认关闭
使用方法:
开启 -XX:+HeapDumpOnOutOfMemoryError
可以通过jinfo -flag [+|-]HeapDumpOnOutOfMemoryError <pid> 或 jinfo -flag HeapDumpOnOutOfMemoryError=<value> <pid> 来动态开启或设置值

  • HeapDumpPath

英文解释:When HeapDumpOnOutOfMemoryError is on, the path(filename or directory) of the dump file(defaults to java_pid<pid>.hprof in the working directory)
中文释义:当HeapDumpOnOutOfMemoryError开启的时候,dump文件的保存路径,默认为工作目录下的java_pid<pid>.hprof文件
使用方法:-XX:HeapDumpPath=/data/dump/jvm.dump
使用经验:除非必要,建议不设置

  • OmitStackTraceInFastThrow

英文解释:Omit backtraces for some ‘hot’ exceptions in optimized code
中文释义:在优化代码里面忽略热点异常回溯
使用方法:
关闭 -XX:-OmitStackTraceInFastThrow
使用经验:某些热点异常抛的太多的话,JVM默认会做优化,会使用JVM初始化的时候创建的异常代替实际的异常,这些异常是没有异常栈信息的,不方便定位问题,如果有碰到这种情况,可以考虑关闭这个配置

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

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

相关文章

学习实践-Vicuna【小羊驼】(部署+运行)

1、Vicuna【小羊驼】-FastChat"更快的对话" 介绍 3 月底&#xff0c;UC伯克利开源大语言模型Vicuna来了&#xff0c;这是一个与 GPT-4 性能相匹配的 LLaMA 微调版本。“缺啥补啥缺啥练啥&#xff0c;傻子也突出”&#xff01; Vicuna 使用从 ShareGPT 收集的用户共…

生成对抗网络GAN

1.基本概念 生成对抗网络Generative Adversarial Networks&#xff08;GAN&#xff09;包含生成模型&#xff08;generative model&#xff09;和判别模型 (discriminative model) 两个模型。生成模型的任务是生成和原始数据相似的实例&#xff0c;判别模型的任务是判断给定的实…

四百左右音质好的蓝牙耳机有哪些?2023公认音质最好的蓝牙耳机排行

与有线耳机相比&#xff0c;蓝牙耳机有着功能多样、使用便捷的优点。最近看到很多人问&#xff0c;四百内音质好的蓝牙耳机有哪些&#xff1f;针对这个问题&#xff0c;我来给大家推荐几款音质最好的蓝牙耳机&#xff0c;一起来看看吧。 一、南卡小音舱Lite2蓝牙耳机 参考价&…

Mybatis(九)插件原理及应用

一、Mybatis的插件实现原理 Mybatis允许用户通过自定义拦截器的方式改变Sql的执行方式&#xff0c;例如在Sql执行时追加Sql分页语法&#xff0c;从而达到减缓分页查询的目的&#xff0c;用户自定义拦截器也被称为Mybatis插件。 我们先从插件的配置及解析过程来分析插件&#…

蓝奥声核心技术分享——基于物联网的无线智能标签刷新控制技术

1.技术背景 基于物联网的无线智能标签刷新控制技术指基于对目标场景状态变化的协同感知而获得触发响应并进行智能决策&#xff0c;属于蓝奥声核心技术--边缘协同感知(EICS&#xff09;技术的关键支撑性技术之一。该项技术涉及物联网边缘域的无线通信与智能控制技术领域。 物联…

学习同步异步的概念,并了解MQ消息队列

文章目录 一、 同步和异步1.1 同步调用1.2 异步调用 二、MQ1.1 介绍1.2 MQ的优点和使用场景 一、 同步和异步 1.1 同步调用 同步调用是一种程序调用方式&#xff0c;在该调用方式中&#xff0c;调用者发起一个请求&#xff0c;然后一直等待被调用者返回响应结果后再继续执行。…

wps - 使用宏来为每行标记序号

在WPS中遇到需要加序号的虽然可以用项目符符号来标注# 但或许用宏更厉害一些 WPS 的宏是一种自动化工具&#xff0c;可以通过编写宏代码来自动执行一些操作&#xff0c;例如创建和编辑文档、打印、格式化等。 WPS 宏的编写可以使用 VBA&#xff08;Visual Basic for Applicat…

236. 二叉树的最近公共祖先 ——【Leetcode每日一题】

236. 二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff…

inode和软硬链接

文章目录&#xff1a; 一、理解文件系统1.1 什么是inode1.2 磁盘了解1.2.1磁盘的硬件结构1.2.2 磁盘的分区1.2.3 EXT2文件系统 二、软硬链接2.1 软链接2.2 硬链接 一、理解文件系统 1.1 什么是inode inodes 是文件系统中存储文件元数据的数据结构。每个文件或目录都有一个唯一…

JavaSE学习进阶day06_01 数据结构(进阶)

第一章 数据结构&#xff08;温习数据结构的内容&#xff09; 1.1 树基本结构介绍 树具有的特点&#xff1a; 每一个节点有零个或者多个子节点 没有父节点的节点称之为根节点&#xff0c;一个树最多有一个根节点。 每一个非根节点有且只有一个父节点 名词含义节点指树中的…

第二届“威固新能源 GO野”,威固重塑新能源出行不凡体验

中国&#xff0c;上海&#xff0c;近日——全球特种材料公司伊士曼旗下汽车膜品牌威固&#xff08;V-KOOL&#xff09;&#xff0c;于近日开启了第二届“威固新能源 GO野”不凡之旅&#xff0c;通过专为新能源而来的创新产品与服务&#xff0c;引领高端新能源车主驶出城市生活的…

晨控可视化标签在资产管理上的应用及优势

晨控可视化标签在资产管理上的应用及优势 资产是企业功能的核心组成部分&#xff0c;是企业重要的基础设施建设。资产存在的形式各种各样&#xff0c;不仅具有价值高、流动性强、安全管理困难的特点&#xff0c;而且成为资产管理的重要环境之一。通过射频识别技术&#xff0c;…

【00-Java Web先导课】-如何进行IDEA的安装

前沿 Pycharm与IDEA激活教程一样&#xff0c;本篇以IDEA激活教程为例进行保姆级教学 文章目录 前沿一、支持系统二、软件版本1.引入库 三、软件下载教程1、点击网址进入jetbrains官网2、按照下图选择相应下载的软件3、按照如图选择需要下载的版本4、按照如下方式进行下载软件 四…

Web服务器

目录 什么是Web服务器&#xff1f; Web容器 Servlet Servlet 规范 Servlet 的API结构 编写Servlet servlet生命周期&#xff08;产生到销毁的过程&#xff09; 服务器产生响应信息的两种格式 什么是Web服务器&#xff1f; Web服务器是一个程序&#xff0c;用于接收客户…

【LeetCode: 718. 最长重复子数组 | 暴力递归=>记忆化搜索=>动态规划】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

Scillus | 来吧!它可以大大简化你的Seurat分析流程哦!~(一)(数据预处理)

1写在前面 太久没更了&#xff0c;真是累到极致&#xff0c;每天回到家都只想睡觉。&#x1f62d; 今天介绍一下Scillus包&#xff0c;是一个基于Seurat和ggplot2的R包&#xff0c;用于增强scRNA-seq数据的处理和可视化。&#x1f9d0; 它可以对Seurat对象进行多种类型的图形展…

多重背包问题的三种解法(转化为01背包、二进制拆分、单调队列优化)

多重背包问题的三种解法 转化为01背包二进制拆分优化单调队列优化 转化为01背包 题目链接:acwing4. 多重背包问题 I 题目描述 数据范围 思路&#xff1a; 可以转化为01背包问题求解&#xff0c;将s个物品都看作单独的一个物品&#xff0c;时间复杂度为 O ( N ∗ V ∗ S ) O(…

【一】MATLAB基础知识

【一】MATLAB基础知识 1 数值数据类型的分类 整型 无符号整数&#xff1a;无符号8位整数、无符号16位整数、无符号32位整数、 无符号64位整数。 带符号整数&#xff1a;带符号8位整数、带符号16位整数、带符号32位整数、 带符号64位整数。 无符号8位整数数据范围&#xff…

树和二叉树(概念及其结构)

1.树概念及结构&#xff08;了解&#xff09;‘ 1.1树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它 叫做树是因为它看起来像一颗倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶…

php+vue+mysql校园大学生兼职信息网站系统

商家功能模块 商家通过点击后台管理&#xff0c;进入页面可以进行首页、个人中心、热门兼职管理、兼职接单管理、学生咨询管理、兼职任务管理、完成评价管理等功能模块&#xff0c;进行相对应操作 兼职接单管理&#xff1a;通过兼职接单管理可以进行获取兼职名称、专业、分类、…