Java内存管理与性能优化实践

Java内存管理与性能优化实践

Java作为一种广泛使用的编程语言,其内存管理和性能优化是开发者在日常工作中需要深入了解的重要内容。Java的内存管理机制借助于垃圾回收(GC)来自动处理内存的分配和释放,但要实现高效的内存管理和优化性能,开发者仍然需要深入理解Java的内存模型、垃圾回收机制以及常见的性能瓶颈。

本文将详细探讨Java内存管理的基本原理,并通过实际的性能优化实践,帮助开发者在开发过程中提升应用的效率。

1. Java内存管理基础

Java的内存管理机制可以归纳为几个关键组件,分别是堆内存、栈内存、方法区(包括类加载器和JVM内部的常量池)等。理解这些组件的内存分配和回收机制,对于开发高效的Java应用至关重要。

1.1 堆内存与栈内存

Java中的内存分为两大主要区域:堆(Heap)和栈(Stack)。这两个区域分别承担不同的功能:

  • 堆内存:用于存储对象及其属性,堆内存是Java内存管理的核心区域,垃圾回收器主要对堆内存进行管理。
  • 栈内存:用于存储局部变量和方法调用的栈帧。栈内存是线程私有的,每个线程都会有自己的栈空间。

1.2 Java的垃圾回收机制

Java的垃圾回收(GC)是自动管理内存的核心机制。GC主要通过标记-清除、复制、标记-整理等算法来回收无用的对象,避免内存泄漏。

  • 标记-清除算法:标记所有可达对象,然后清除未标记的对象。
  • 复制算法:将内存分为两个区域,每次只使用一个区域,回收时将存活的对象复制到另一区域。
  • 标记-整理算法:与标记-清除相似,但在清理后进行整理,减少内存碎片。

在JVM中,GC的实现是分代进行的,堆内存被划分为新生代、老年代和永久代(在JVM 8以后,永久代被元空间替代)。

2. 性能优化策略

在开发Java应用时,性能优化往往依赖于对内存的合理管理和垃圾回收机制的理解。以下是几种常见的优化策略:

2.1 减少GC频率和停顿时间

垃圾回收频率和停顿时间是影响应用性能的关键因素。频繁的GC会增加系统的负担,导致性能下降。为了减少GC的影响,可以采取以下措施:

  • 对象池化:通过对象池技术,复用对象而非频繁创建和销毁对象,减少GC的压力。
  • 手动管理内存:尽量避免创建过多的临时对象,特别是在循环中。
  • 合理设置JVM参数:通过调整JVM的堆内存大小、GC类型等来优化垃圾回收的效率。
示例:调整JVM参数

在启动应用时,可以通过以下JVM参数调整垃圾回收的行为:

java -Xms1024m -Xmx2048m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar myapp.jar
  • -Xms1024m:设置JVM初始堆内存为1024MB。
  • -Xmx2048m:设置JVM最大堆内存为2048MB。
  • -XX:+UseG1GC:启用G1垃圾回收器。
  • -XX:MaxGCPauseMillis=200:设置最大GC暂停时间为200毫秒。

2.2 内存泄漏的检测与防止

内存泄漏是指程序无法释放不再使用的对象,导致内存消耗逐渐增加。常见的内存泄漏原因包括:

  • 静态集合类:静态集合类持有大量对象,且没有及时清理,可能导致内存泄漏。
  • 事件监听器未移除:对象注册了事件监听器,但在不再需要时没有移除,导致对象无法被GC回收。
  • 内存泄漏检测工具:可以使用工具如VisualVM、JProfiler、MAT(Memory Analyzer Tool)来分析内存泄漏。
示例:防止静态集合类导致内存泄漏
public class Cache {private static Map<String, Object> cache = new HashMap<>();public static void put(String key, Object value) {cache.put(key, value);}public static Object get(String key) {return cache.get(key);}public static void remove(String key) {cache.remove(key);}
}

上述代码中,cache是一个静态字段,它会导致缓存数据无法被GC回收。如果没有显式地调用remove方法移除缓存中的对象,就可能造成内存泄漏。使用WeakHashMap代替HashMap可以防止内存泄漏。

2.3 优化堆内存分配

合理分配堆内存大小对于提高Java应用的性能至关重要。堆内存过大或过小都可能导致性能问题。

  • 过大:JVM会使用更多的内存,GC暂停时间增加,且可能会频繁发生Full GC。
  • 过小:频繁进行Young GC,导致响应时间变慢。

通过合理设置JVM参数,进行堆内存的调优:

java -Xms512m -Xmx2048m -XX:+UseG1GC -XX:NewSize=512m -jar myapp.jar
  • -Xms512m:设置初始堆内存为512MB。
  • -Xmx2048m:设置最大堆内存为2048MB。
  • -XX:NewSize=512m:设置新生代大小为512MB。

2.4 使用合适的数据结构

选择合适的数据结构对内存的使用和程序的执行效率有重要影响。例如,使用ArrayList替代LinkedList来减少内存消耗和提高访问速度,使用HashMap替代TreeMap来提高查找效率等。

示例:优化内存使用
// 使用ArrayList代替LinkedList来减少内存消耗
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {list.add(i);
}// 使用HashMap代替TreeMap来提高查找效率
Map<Integer, String> map = new HashMap<>();
for (int i = 0; i < 1000; i++) {map.put(i, "value" + i);
}

通过选择适合的集合类,可以减少内存占用并提高程序的性能。

2.5 JVM性能调优工具

在Java应用中进行性能优化时,合理使用JVM调优工具是必不可少的。以下是几款常用的JVM性能分析工具:

  • jvisualvm:用于监控JVM的性能、内存使用情况和线程活动。
  • jprofiler:强大的性能分析工具,可以用于分析内存泄漏、CPU性能瓶颈等问题。
  • MAT(Memory Analyzer Tool):用于分析堆转储文件,检测内存泄漏。

3. 实践案例:优化一个Java Web应用

假设我们有一个Java Web应用,需要对其进行内存管理和性能优化。以下是优化步骤:

  1. 分析GC日志:启用GC日志,查看GC频率和停顿时间。
java -Xlog:gc* -jar mywebapp.jar
  1. 调整堆内存参数:根据GC日志分析结果,调整堆内存的初始和最大值。
java -Xms1024m -Xmx2048m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar mywebapp.jar
  1. 优化数据库连接池:确保数据库连接池大小适中,避免过多连接占用内存。
  2. 减少对象创建:避免在频繁调用的方法中创建临时对象,使用对象池技术重用对象。
  3. 内存泄漏检查:使用VisualVM检查内存泄漏,识别并修复静态集合类和事件监听器问题。

4. 实践案例:优化一个Java Web应用

假设我们有一个Java Web应用,该应用在高并发情况下表现出内存不足和响应缓慢的现象。我们将通过以下几个步骤来优化内存管理与性能,提升系统的稳定性和响应速度。

4.1 启用并分析GC日志

GC日志能够帮助我们了解垃圾回收的行为及其对应用性能的影响。通过分析GC日志,可以确定GC发生的频率、停顿时间和堆内存使用情况,从而优化堆大小及GC策略。

首先,启用GC日志:

java -Xlog:gc* -jar mywebapp.jar

通过查看GC日志,分析以下几个关键数据点:

  • GC频率:频繁的Full GC可能意味着堆内存设置过小,或者有大量的临时对象产生。
  • GC停顿时间:如果GC停顿时间过长,可能导致应用响应延迟。可以通过调整JVM参数(如-XX:MaxGCPauseMillis)来优化停顿时间。
  • 堆内存使用情况:GC日志能够帮助我们分析堆内存是否已充分利用,并决定是否需要调整堆内存的大小。

4.2 调整堆内存参数

通过GC日志的分析结果,我们可以决定堆内存的初始大小和最大值。在我们的案例中,我们通过调整堆内存来减少GC的频率和停顿时间。

假设GC日志显示频繁发生Full GC,且堆内存大小较小,可以将堆内存的初始大小(-Xms)和最大大小(-Xmx)增加,并使用G1垃圾回收器以减少停顿时间。

java -Xms2048m -Xmx4096m -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar mywebapp.jar
  • -Xms2048m:设置JVM初始堆内存为2048MB。
  • -Xmx4096m:设置JVM最大堆内存为4096MB。
  • -XX:+UseG1GC:启用G1垃圾回收器,它在低延迟和高吞吐量之间做出平衡。
  • -XX:MaxGCPauseMillis=200:将GC停顿时间限制为200毫秒以内,帮助提高应用的响应性。

4.3 优化数据库连接池

数据库连接池是一个常见的性能瓶颈。在Web应用中,数据库连接的创建和销毁会耗费大量的资源。合理配置数据库连接池,可以减少连接的开销,提升数据库访问性能。

我们可以使用常见的数据库连接池库,如HikariCP、C3P0等。下面是使用HikariCP配置数据库连接池的示例:

<!-- 在application.properties中配置HikariCP -->
spring.datasource.hikari.minimum-idle=10
spring.datasource.hikari.maximum-pool-size=50
spring.datasource.hikari.idle-timeout=30000
spring.datasource.hikari.max-lifetime=600000
  • minimum-idle:池中最小的空闲连接数。设置为10意味着即使连接池中没有请求,连接池也会保持10个连接空闲。
  • maximum-pool-size:连接池的最大连接数,设置为50意味着最多可以有50个数据库连接同时处于活动状态。
  • idle-timeout:连接在池中空闲时的最大时间,超过该时间会被回收。
  • max-lifetime:连接的最大生命周期,超过该时间会被关闭并重新创建。

通过适当配置数据库连接池,可以有效减少数据库连接的创建与销毁开销,提高数据库访问效率,进而提升整体应用性能。

4.4 减少临时对象的创建

在Java中,频繁地创建临时对象会增加GC的负担,导致内存占用过高。为了减少GC的频繁触发,我们需要尽量避免在循环或高频调用的方法中创建临时对象。

示例:优化循环中的对象创建
// 不优化的代码:每次循环都创建一个新的String对象
for (int i = 0; i < 1000; i++) {String result = "Item " + i;process(result);
}// 优化后的代码:避免在循环中频繁创建对象
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {sb.setLength(0); // 清空缓存区sb.append("Item ").append(i);process(sb.toString());
}

在优化后的代码中,我们避免在每次循环时创建新的String对象,而是重用StringBuilder来构造字符串。这种优化减少了对象的创建和GC的负担。

4.5 监控并优化线程池

高并发应用中,线程池的使用至关重要。合理配置线程池的大小可以避免线程的频繁创建与销毁,减少系统资源的消耗,同时避免线程饥饿(线程数过少)或线程阻塞(线程数过多)。

我们可以使用Executors来创建线程池,并根据业务需求设置合理的线程池参数:

// 使用ThreadPoolExecutor创建自定义线程池
int corePoolSize = 10;
int maxPoolSize = 50;
long keepAliveTime = 60L;
TimeUnit unit = TimeUnit.SECONDS;ExecutorService executor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, unit, new LinkedBlockingQueue<>()
);// 提交任务
executor.submit(() -> {// 执行任务
});
  • corePoolSize:核心池大小,线程池中始终保持的线程数。
  • maxPoolSize:最大线程数,线程池能够容纳的最大线程数。
  • keepAliveTime:当线程池中的线程空闲时,保持的最大时间。

通过合理配置线程池的大小,可以提高线程的复用性,减少线程创建和销毁的开销,从而提升应用的性能。

4.6 内存泄漏的检查与修复

内存泄漏是影响Java应用性能的常见问题,尤其是在高并发和长时间运行的应用中。Java内存泄漏通常发生在对象未能及时释放,导致它们一直占用内存空间。

使用VisualVM等工具可以帮助我们监测应用的内存使用情况并定位内存泄漏。

  • 常见的内存泄漏原因

    • 静态集合类持有大量对象,未能及时清理。
    • 事件监听器未解除注册。
    • 使用不当的第三方库,导致对象引用未被释放。
示例:检测内存泄漏
// 内存泄漏示例:静态集合类导致的内存泄漏
public class Cache {private static Map<String, Object> cache = new HashMap<>();public static void addToCache(String key, Object value) {cache.put(key, value);}public static Object getFromCache(String key) {return cache.get(key);}
}

在上述代码中,Cache类的cache是一个静态成员,它会一直持有对添加到缓存中的对象的引用。如果不定期清理这些对象,cache将不断增长,最终导致内存泄漏。

为了解决这个问题,可以使用WeakHashMap来代替HashMap,从而使得缓存中的对象能够在没有强引用时被GC回收:

public class Cache {private static Map<String, Object> cache = new WeakHashMap<>();public static void addToCache(String key, Object value) {cache.put(key, value);}public static Object getFromCache(String key) {return cache.get(key);}
}

WeakHashMap中的对象在没有强引用时会被GC回收,从而避免了内存泄漏问题。

5. 高效的垃圾回收调优

随着应用的复杂度增加,垃圾回收的调优变得尤为重要。通过选择合适的垃圾回收策略,可以有效降低GC的开销,提高应用的性能。

常用的垃圾回收器有:

  • Serial GC:适用于单核机器或内存较小的系统,适用于小型应用。
  • Parallel GC:适用于多核机器,能够充分利用CPU资源,适合处理高吞吐量任务。
  • G1 GC:适用于大内存、高并发的系统,能够提供较低的GC停顿时间和较好的吞吐量。
  • ZGC(Z Garbage Collector)和Shenandoah GC:低延迟的垃圾回收器,适用于需要响应时间低的应用。

可以根据实际需求选择适合的GC策略,并通过-XX:+PrintGCDetails来打印GC日志,以便进一步分析和优化。

6. JVM性能监控与调优工具

在Java应用的性能优化过程中,JVM性能监控和调优工具是不可或缺的,它们可以帮助开发者深入分析内存使用、GC行为、线程活动等,从而找出性能瓶颈并进行有效的优化。

6.1 使用JVM工具分析GC和内存

VisualVM

VisualVM是JVM的一种图形化监控工具,能够帮助开发者查看JVM的运行状态,包括内存、线程、垃圾回收等信息。它可以连接到正在运行的JVM进程,并提供如下功能:

  • 内存分析:查看堆内存使用情况,帮助发现内存泄漏。
  • CPU分析:查看CPU使用率,识别CPU占用高的线程。
  • 线程分析:查看线程的状态和活动,帮助找出阻塞的线程。

启动VisualVM并连接到JVM后,可以通过以下步骤分析GC和内存:

  1. 监控堆内存:点击Heap Dump,分析堆内存使用情况和对象分布。
  2. GC监控:通过GC选项查看垃圾回收日志,分析GC频率和停顿时间。
  3. 查看线程状态:在Threads标签页中查看当前线程状态,定位线程饥饿和死锁问题。
jstat

jstat是JVM自带的一个命令行工具,主要用于监控JVM的性能指标,如垃圾回收情况、堆内存使用等。它可以实时输出堆内存、垃圾回收统计数据,帮助开发者了解JVM的运行状态。

例如,使用以下命令来监控GC信息:

jstat -gcutil <pid> 1000
  • <pid>:JVM进程的ID。
  • 1000:表示每秒输出一次统计信息。

这将输出类似以下信息:

 S0C    S1C    S0U    S1U    EC      EU     OC     OU     YGC    YGCT    FGC    FGCT    GCT1024.0 1024.0 0.0    0.0    8192.0  500.0  4096.0  1024.0 10     0.005   2     0.05    0.055

这些数据显示了不同内存区域的使用情况,帮助我们分析GC的频率和堆的使用情况。

6.2 使用JProfiler进行深度分析

JProfiler是一款强大的Java性能分析工具,专门用于分析内存、CPU、线程等性能瓶颈。它提供了对堆内存使用、内存泄漏、CPU消耗等方面的详细分析,适合用来做深度性能优化。

内存分析

JProfiler可以通过堆转储分析来帮助我们定位内存泄漏。它允许开发者:

  • 查看对象分配:分析哪些类的对象最占用内存。
  • 查看对象引用链:跟踪对象的引用路径,找出导致内存泄漏的根本原因。
  • 堆转储:导出堆转储文件进行后期分析。
CPU分析

通过JProfiler的CPU分析功能,可以深入查看应用中哪些方法调用最占用CPU。它提供了详细的堆栈跟踪信息,帮助定位性能瓶颈。

分析线程

JProfiler还能够监控线程的活动,分析线程的生命周期和阻塞情况,找出潜在的线程问题,如死锁和线程饥饿。

6.3 使用Prometheus和Grafana进行JVM监控

Prometheus和Grafana是现代分布式应用监控的标配工具,特别适用于监控Java微服务和高并发应用。我们可以通过jmx_exporter将JVM指标暴露给Prometheus,然后使用Grafana可视化这些指标。

配置Prometheus与JMX Exporter

首先,下载并配置jmx_exporter,将JVM指标暴露到Prometheus:

java -javaagent:/path/to/jmx_exporter.jar=9404:/path/to/jmx_exporter_config.yaml -jar myapp.jar
  • 9404是暴露JVM指标的端口。
  • jmx_exporter_config.yaml是JMX Exporter的配置文件。

然后,通过Prometheus拉取JVM指标,配置Prometheus与Grafana来展示这些数据,例如:

scrape_configs:- job_name: 'java'static_configs:- targets: ['localhost:9404']

通过Grafana的Dashboard,可以直观地看到内存使用情况、垃圾回收时间、线程活动等指标。

7. 高效的垃圾回收调优

垃圾回收(GC)是JVM性能优化的关键之一,GC的调优可以显著减少应用的响应时间,提升系统的吞吐量。以下是几个常见的垃圾回收调优方法:

7.1 选择合适的垃圾回收器

JVM提供了多种垃圾回收器,每种回收器适用于不同的场景。选择合适的垃圾回收器可以提高GC效率,减少GC停顿时间。

  • Serial GC:适合单核机器或内存较小的应用,优点是实现简单,缺点是并发性能差。
  • Parallel GC:适用于多核机器,能够提供更好的吞吐量,适用于批处理或非实时应用。
  • G1 GC:适用于大内存、低延迟的应用,能够控制GC停顿时间,适合需要高响应的应用。
  • ZGC/Shenandoah:新一代低延迟垃圾回收器,适用于对响应时间要求极高的应用。

可以通过JVM启动参数选择适合的垃圾回收器,例如:

java -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -jar myapp.jar

7.2 调整GC暂停时间

JVM的GC停顿时间会直接影响应用的响应时间,特别是在高并发和大内存应用中。通过调整MaxGCPauseMillisG1HeapRegionSize等参数,可以控制GC的停顿时间。

  • MaxGCPauseMillis:设置最大GC停顿时间,JVM会尽力在此时间内完成GC,适用于低延迟要求的应用。
  • G1HeapRegionSize:调整G1 GC区域的大小,优化GC的内存分配。
java -XX:+UseG1GC -XX:MaxGCPauseMillis=100 -XX:G1HeapRegionSize=8m -jar myapp.jar

通过这些参数的调整,可以实现较低的GC停顿时间,保证系统的响应能力。

7.3 调整堆内存大小

堆内存的大小直接影响GC的效率。较小的堆内存可能导致频繁的GC,较大的堆内存可能导致Full GC时的长时间停顿。我们需要根据应用的内存需求来调整堆内存的大小。

通过以下参数可以设置堆内存的初始大小和最大大小:

java -Xms1024m -Xmx2048m -XX:+UseG1GC -jar myapp.jar
  • -Xms1024m:设置初始堆内存为1024MB。
  • -Xmx2048m:设置最大堆内存为2048MB。

通过调整堆的大小,可以避免频繁的Young GC和Full GC,从而提升应用性能。

8. 使用JVM日志分析工具

JVM日志分析工具能够帮助开发者深入了解JVM的运行情况,特别是在GC调优和内存管理方面。

8.1 GC日志分析

GC日志记录了垃圾回收的详细信息,包括GC的类型、停顿时间、堆内存的使用情况等。使用GC日志分析工具,如GCViewerJClarity等,可以帮助我们识别性能瓶颈。

启用GC日志

使用以下JVM参数启用GC日志:

java -Xlog:gc* -jar myapp.jar

通过GC日志,我们可以分析出GC频率、停顿时间、堆内存使用等指标,从而进行优化。

总结

Java内存管理与性能优化是确保高效、可扩展应用的关键因素。本文深入探讨了Java内存管理的核心概念、常见的内存优化策略,以及通过具体实践案例如何提升应用性能。以下是本篇文章的主要内容总结:

  1. 内存管理基础
    • 堆内存与非堆内存:了解堆内存、方法区、直接内存等内存区域的分配与使用。
    • 垃圾回收(GC)机制:分析GC的工作原理,及其对应用性能的影响。
  2. 性能优化实践
    • 通过启用GC日志和分析堆内存使用情况,合理调整堆大小,选择适合的垃圾回收器来减少停顿时间。
    • 优化数据库连接池、线程池等资源的配置,以提高应用的吞吐量和响应速度。
    • 避免频繁的对象创建,通过重用对象和使用合适的数据结构,减少内存消耗和GC的负担。
  3. 监控与分析工具
    • VisualVMJProfilerPrometheusGrafana等工具可以帮助开发者实时监控JVM的内存使用、GC行为、线程活动等,提供深入的性能分析。
    • GC日志分析工具(如GCViewer、JClarity)能够帮助开发者识别GC瓶颈并优化GC策略。
  4. 垃圾回收调优
    • 选择适合的垃圾回收器(如G1、ZGC等)根据应用需求调整GC策略,以减少GC停顿时间并优化内存利用。
    • 调整堆内存大小,控制GC的频率与停顿时间,避免Full GC和过度的内存消耗。
  5. 内存泄漏的监控与修复
    • 使用堆转储分析工具,如VisualVMJProfiler等,检测内存泄漏的根本原因,并通过改进代码结构(如使用WeakHashMap)来避免内存泄漏问题。

通过对JVM内存管理和性能优化的深入理解及实践,开发者可以有效地提升应用性能,避免内存瓶颈和GC问题,从而确保Java应用的高效运行。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

解码中国AI双雄突围:DeepSeek破壁与英伟达反攻背后的算力暗战

一、算力困局下的中国突围术 2024年夏季的科技界暗流涌动&#xff1a;北京中关村的服务器机房里&#xff0c;寒武纪最新MLU300X芯片正以每秒120万亿次运算支撑着自动驾驶系统的实时决策&#xff1b;上海张江的AI实验室中&#xff0c;DeepSeek团队通过神经元分块技术将模型参数压…

【Python · Pytorch】Conda介绍 DGL-cuda安装

本文仅涉及DGL库介绍与cuda配置&#xff0c;不包含神经网络及其训练测试。 起因&#xff1a;博主电脑安装了 CUDA 12.4 版本&#xff0c;但DGL疑似没有版本支持该CUDA版本。随即想到可利用Conda创建CUDA12.1版本的虚拟环境。 1. Conda环境 1.1 Conda环境简介 Conda&#xff1…

0x03 http协议和分层架构

HTTP协议 简介 Hyper Text Transfer Protocol&#xff0c;超文本传输协议&#xff0c;规定了浏览器和服务器之间数据传输的规则 http协议基于TCP协议&#xff1a;面向连接&#xff0c;安全基于请求-响应模型&#xff1a;一次请求对应一次响应HTTP协议是无状态的协议&#xff…

IDEAPyCharm安装ProxyAI(CodeGPT)插件连接DeepSeek-R1教程

背景&#xff1a;最近DeepSeek比较火嘛&#xff0c;然后在githup上也看到了GitHub Copilot&#xff0c;就想着现在AI的准确率已经可以提高工作效率了。所以从网上找了一些编程插件&#xff0c;发现Proxy支持的模型比较多&#xff0c;通用性和适配性比较好。所以本文记录一下pro…

qt-C++笔记之QToolButton和QPushButton的区别

qt-C笔记之QToolButton和QPushButton的区别 code review! 文章目录 qt-C笔记之QToolButton和QPushButton的区别1.运行2.main.cpp3.main.pro 1.运行 QToolButton 适用于工具栏或需要较紧凑、图标化显示的场合。通过 setAutoRaise(true) 与 setToolButtonStyle(Qt::ToolButtonTe…

css的元素显示模式

一.什么是元素显示模式 作用&#xff1a;网页的标签非常多&#xff0c;不同地方会用到不同类型的标签&#xff0c;了解他们的特点可以更好的布局我们的网页。 元素显示模式就是元素(标签)以什么方式进行显示&#xff0c;比如<div>自己占一行&#xff0c;比如一行可以放多…

MySQL整体架构

目录 1 客户端 2 服务端 2.1 Server层 2.1.1 连接器 2.1.2 查询缓存 2.1.3 词法器 2.1.4 优化器 2.1.5 执行器 2.2 存储引擎层 1 客户端 ● 客户端为连接MySQL服务端的工具或者驱动&#xff0c;比如JDCB&#xff0c;ODBC等等 ● 用于连接目前服务器&#xff0c;并且发送需要执行…

【踩坑随笔】`npm list axios echarts`查看npm依赖包报错

npm list axios echarts查看npm依赖包出现以下报错&#xff0c;原因就是包的版本匹配问题&#xff0c;按照提示降axios版本或者自己升找合适的got版本&#xff0c;我这里是选择了降版本。本文记录仅做解决思路参考不一定适配大家的实际情况。 weed-detection-system1.0.0 E:\P…

大唐杯——阶段二01

03 5G寻呼 UE&#xff08;User Equipment&#xff09; UE是用户设备&#xff08;User Equipment&#xff09;的缩写&#xff0c;指的是移动通信网络中的终端设备&#xff0c;例如手机、平板电脑、物联网传感器等。 AMF&#xff08;Access and Mobility Management Function&a…

小程序画带圆角的圆形进度条

老的API <canvas id"{{canvasId}}" canvas-id"{{canvasId}}" style"opacity: 0;" class"canvas"/> startDraw() {const { canvasId } this.dataconst query this.createSelectorQuery()query.select(#${canvasId}).bounding…

SimVS: Simulating World Inconsistencies for Robust View Synthesis 论文解读

目录 一、概述 二、相关工作 三、SimVS 1、利用视频模型模拟世界的不一致性 2、效果 一、概述 该论文提出了一种名为SimVS的视频模型方法&#xff0c;旨在解决稀疏多视角图像捕捉中因动态变化&#xff08;光照变化、物体运动&#xff09;导致的视图合成鲁棒性问题。 动机&a…

华为OD机试真题:跳房子I (E卷、Java)

华为OD机试&#xff08;E卷D卷C卷&#xff09;最新题库【超值优惠】Java/Python/C合集 题目描述 跳房子&#xff0c;也叫跳飞机&#xff0c;是一种世界性的儿童游戏。 游戏参与者需要分多个回合按顺序跳到第1格直到房子的最后一格。跳房子的过程中&#xff0c;可以向前跳&…

快速排序算法详解

算法原理 快速排序是一种分治的策略的排序算法。它的核心排序思想是将问题不断的分解为子问题。以数组为例进行介绍更容易理解&#xff0c;创建一个数组或者vector&#xff0c;假设是std::vector<int> a{3&#xff0c;2, 1, 5, 4,7}&#xff0c;要对a从小到大进行排序&a…

Windows本地Docker+Open-WebUI部署DeepSeek

最近想在自己的电脑本地部署一下DeepSeek试试&#xff0c;由于不希望污染电脑的Windows环境&#xff0c;所以在wsl中安装了ollama&#xff0c;使用ollama拉取DeepSeek模型。然后在Windows中安装了Docker Desktop&#xff0c;在Docker中部署了Open-WebUI&#xff0c;最后再在Ope…

题解 | 牛客周赛82 Java ABCDEF

目录 题目地址 做题情况 A 题 B 题 C 题 D 题 E 题 F 题 牛客竞赛主页 题目地址 牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ 做题情况 A 题 判断字符串第一个字符和第三个字符是否相等 import java.io.*; import java.math.*; import java.u…

Codeforces Round 1007 (Div. 2)(ABCD1)

A. The Play Never Ends 翻译&#xff1a; 让我们来介绍一种双人游戏--乒乓球&#xff0c;在这种游戏中&#xff0c;胜负永远分明&#xff0c;不可能出现平局。 索赛、福福和浩海三人想用一生的时间打乒乓球。他们决定用以下方式永远打下去&#xff1a; 在每场比赛中&#xff…

swift 开发效率提升工具

安装github copliot for xcode github/CopilotForXcode brew install --cask github-copilot-for-xcode安装swiftformat for xcode brew install swiftformatXcode Swift File代码格式化-SwiftFormat

蜂鸣器使用

1、蜂鸣器原理 无源蜂鸣器模块根据输入的 不同方波信号&#xff08;作为震荡源&#xff09;可以发出不同的声音。驱动电路中三极管电阻一般为1K-4K都行&#xff0c;能够让三极管导通即可。&#xff08;三极管即带箭头的部分&#xff0c;基极和发射机&#xff08;PNP&#xff09…

drawDB:一款免费数据库设计工具

drawDB 是一款基于 Web 的免费数据库设计工具&#xff0c;通过拖拽、复制、粘贴等方式进行数据库建模设计&#xff0c;同时可以生成相应的 SQL 脚本。 功能特性 drawDB 目前可以支持 MySQL、MariaDB、PostgreSQL、SQL Server 以及 SQLite 数据库&#xff0c;核心功能包括&…

【AI论文】将1568个标记压缩到单个向量中并再解压:探索嵌入空间容量的极限

摘要&#xff1a;近期&#xff0c;一系列研究致力于解决将标记序列压缩为更短的实值向量序列的问题&#xff0c;这些向量序列将作为输入&#xff0c;替代标记嵌入或键值缓存。这些方法有助于减少现有语言模型中的计算量。尽管使用了强大的模型作为编码器&#xff0c;但无损压缩…