当前位置: 首页 > news >正文

如何有效判断与排查Java GC问题

目录

一、GC的重要性与对性能的影响

(一)GC对性能的影响简要分析

1.GC暂停与应用停顿

2.GC吞吐量与资源利用率

3.GC对内存管理的作用:资源回收

4.GC策略与优化的选择

(二)GC的双刃剑

二、GC性能评价标准

(一)GC性能评价标准:延迟(Latency)与吞吐量(Throughput)

1. 延迟STW(Latency)

2. 吞吐量(Throughput)

(二)SLA与实际业务需求的结合

1.如何结合SLA和GC性能

2.SLA与实际业务需求的平衡

三、GC Cause 与触发

(一)GCCause 类概述常见触发原因

1.手动触发GC

2.垃圾回收频率过高

3.内存分配相关

4.JVM内部的GC策略与调整

5.CMS(Concurrent Mark-Sweep)收集器相关

6.G1(Garbage First)垃圾回收器相关

7.白盒(WhiteBox)工具触发的GC

8.其他

(二)GCCause::to_string 方法解析

(三) GC触发逻辑的关键代码

(四)如何根据 GCCause 优化GC策略?

四、判断GC问题是否是根因

(一)时序分析:事件发生的时间顺序

1.基本步骤

2.关键点

(二)概率分析:历史问题的参考

1.基本步骤

2.关键点

(三)实验分析:通过模拟验证假设

1.基本步骤

2.关键点

(四)反证分析:验证表象与问题的相关性

1.基本步骤

2.关键点

五、GC 问题分类导读

(一)Mutator 类型:根据对象存活时间的分布进行分类

1.IO 交互型

2.MEM 计算型

(二)GC 问题分类

(三)排查难度

1.常见问题

2.较复杂问题

3.高难度问题

六、总结


干货分享,感谢您的阅读!

在现代Java应用中,垃圾回收(GC)是一个不可忽视的重要环节。尽管GC自动管理内存,避免了手动释放资源的麻烦,但它带来的性能开销却常常困扰开发者。从GC暂停时间到吞吐量影响,如何在保证应用稳定性的同时,优化GC的性能,是每个Java开发者面临的挑战。本文将深入探讨GC的基本原理、常见策略及调优方法,帮助你更好地理解GC背后的机制,解决GC相关的性能瓶颈,提升应用的响应速度和吞吐量。

 历史主要基本文章回顾:

涉猎内容具体链接
Java GC 基础知识快速回顾Java GC 基础知识快速回顾-CSDN博客
垃圾回收基本知识内容Java回收垃圾的基本过程与常用算法_java垃圾回收过程-CSDN博客
CMS调优和案例分析CMS垃圾回收器介绍与优化分析案列整理总结_cms 对老年代的回收做了哪些优化设计-CSDN博客
G1调优分析Java Hotspot G1 GC的理解总结_java g1-CSDN博客
ZGC基础和调优案例分析垃圾回收器ZGC应用分析总结-CSDN博客

从ES的JVM配置起步思考JVM常见参数优化

从ES的JVM配置起步思考JVM常见参数优化_es jvm配置-CSDN博客
高频面试题汇总JVM高频基本面试问题整理_jvm面试题-CSDN博客

一、GC的重要性与对性能的影响

GC(垃圾回收)在Java等编程语言中的重要性,根本上源于它对内存管理的作用。简单来说,GC是“自动化的内存清理工人”,它的任务是清理不再使用的对象,防止内存泄漏和内存溢出问题。然而,虽然GC是自动进行的,它也有着不可忽视的性能代价,尤其是当它没有被合理配置时。

(一)GC对性能的影响简要分析

1.GC暂停与应用停顿

GC过程中,应用程序暂停的时间(也叫STW,Stop-the-World)是一个明显的性能影响因素。在进行垃圾回收时,JVM会暂停所有的应用线程,执行内存的清理工作。尤其在老年代(Old Generation)GC或Full GC时,这种停顿时间会显著增加。

假设某个服务需要响应用户请求,当GC暂停时,所有的请求都无法得到处理。对于实时性要求高的服务,长时间的GC停顿会让用户体验下降,甚至直接影响到服务的稳定性。比如电商网站,处理订单请求时,GC停顿了200ms。如果这个时间超出了客户体验的容忍度,用户就会感受到卡顿,甚至可能放弃订单。

2.GC吞吐量与资源利用率

GC不仅消耗时间,还会消耗系统资源。JVM的GC线程会占用系统的CPU和内存,导致原本用于处理业务逻辑的资源被分配给垃圾回收。吞吐量是衡量这些资源分配的一个重要指标,表示应用程序在系统中有效执行的时间与总时间的比例。

例如,如果系统花了大量时间在GC上,吞吐量就会降低,导致系统的整体性能下降。高吞吐量的应用通常需要较少的GC时间,而低延时的应用则需要精细调控GC的频率和停顿时间。在工作中如果一个数据处理系统的吞吐量降低,意味着在一定时间内,它能处理的请求或任务量变少,可能导致响应变慢,服务性能下降。

3.GC对内存管理的作用:资源回收

另一方面,GC也能优化内存的使用,及时回收不再使用的对象。对于内存消耗较大的应用,如果不进行GC回收,系统可能会因为内存不足而出现OOM(Out Of Memory)错误,甚至崩溃。

大规模数据处理的系统,如果长时间不进行GC,内存会被占满,可能导致OutOfMemoryError,进而导致应用崩溃。这部分日常发生一旦发生,必须定位主要原因,因为一味的反复重启起不到关键作用!

4.GC策略与优化的选择

JVM中有不同的垃圾回收策略,例如:Serial GC、Parallel GC、CMS、G1等,每种策略对性能的影响不同。不同的应用场景需要选择不同的GC策略。如果一个低延迟要求的应用使用了G1或CMS,可能会减少GC停顿时间,但会增加GC的频率,反之,如果选择吞吐量优先的策略,则可能会导致长时间的GC停顿。

如电商网站的订单处理系统,可能更适合低延迟的GC策略,如G1,而一个批量数据处理系统,可能更适合吞吐量优化的策略,如Parallel GC。

(二)GC的双刃剑

GC看起来是一个自动化的内存管理工具,可以帮助我们免去手动管理内存的麻烦。但实际上,GC带来的问题,尤其是在高并发、高实时性要求的应用中,可能会变成一个性能瓶颈。它的两个关键性能指标——延迟和吞吐量,是相互制约的。

  • 延迟优先的场景下,我们追求较短的GC停顿时间,不希望GC影响到应用的响应速度。
  • 吞吐量优先的场景下,我们则关注如何让GC尽可能少地占用系统资源,提高业务处理效率,但这种策略往往伴随着较长的GC停顿时间。

因此,GC是一个精细化的权衡游戏。在性能优化过程中,不仅要评估应用的业务需求,还要根据系统的实际运行情况、内存分配策略、GC日志等,来做出调整。错误的GC配置会让你付出“沉默的代价”——那就是系统的性能下降,而这种下降往往并不是一眼能看到的,得通过分析日志、监控指标,甚至在压力测试中反复验证。

二、GC性能评价标准

(一)GC性能评价标准:延迟(Latency)与吞吐量(Throughput)

在GC优化和排查的过程中,延迟(Latency)和吞吐量(Throughput)是两个最关键的性能指标。理解这两个指标,并根据实际业务需求进行平衡,是保证系统稳定性和性能的核心。

1. 延迟STW(Latency)

延迟通常是指垃圾回收过程中,JVM停顿的时间,简称“STW(Stop-the-World)时间”。在GC过程中,应用的所有线程会暂停,直到GC完成,才会继续执行。延迟就是这种暂停的时长。

对于许多业务来说,尤其是高实时性、低延迟的应用,GC延迟的控制至关重要。假如GC的延迟过长,会导致系统的响应时间增加,从而影响用户体验和系统的实时处理能力。

如何衡量

  • 最大停顿时间:即一次GC执行时,停顿的最大时间。通常,低延迟应用会对这个最大停顿时间有严格的要求,比如要求每次GC的最大停顿时间不超过几毫秒(例如80ms)。
  • 99%延迟:对于大部分的应用来说,99%的GC停顿时间应该不超过某个值。举个例子,TP99(即响应时间的99百分位)在80ms以下,就表示这部分大多数GC暂停时间都在80ms以内。

典型问题

  • 长时间GC停顿:例如,CMS或G1垃圾回收器在执行Full GC时可能会有较长的停顿时间,尤其在老年代(Old Generation)需要回收时,停顿时间可能会超过业务需求。
  • 频繁的Minor GC:过度频繁的年轻代GC(如Young GC)会增加应用的停顿时间,尤其当Young区内存较小或应用的内存需求较大时。

控制延迟的手段

  • 选择合适的GC收集器:G1垃圾回收器能够在一定程度上控制最大停顿时间,并且可以设置目标停顿时间。而CMS在低延迟场景下也有不错的表现,但需要注意的是,它的Final Remark阶段会出现长时间的停顿。
  • 调整GC参数:例如,调节Young Generation的大小、设置合适的GC线程数、优化Old Generation的内存分配等。

2. 吞吐量(Throughput)

吞吐量指的是在一个时间段内,JVM用于执行应用程序业务代码的时间占总时间的比例。具体来说,吞吐量 = (应用程序执行时间) / (总运行时间)。换句话说,吞吐量越高,表示系统有更多的时间用于处理业务逻辑,而不是用于垃圾回收。

吞吐量对于大多数的业务系统来说,尤其是批量处理、数据分析等计算密集型应用至关重要。如果GC占用了过多的CPU资源,那么应用程序的执行时间就会受到影响,吞吐量就会下降,导致系统的处理能力和并发能力受限。

如何衡量

  • 系统吞吐量:如果系统运行了100分钟,其中30分钟用于GC,那么吞吐量就是70%(即系统有效执行的时间占总时间的百分比)。
  • GC占比:通过监控GC消耗的时间比例来判断吞吐量。例如,如果一个应用的GC占比超过10%,就表示GC可能是系统性能瓶颈的一个重要来源。

典型问题

  • GC过于频繁:如果GC占用了过多的CPU资源,导致应用程序的业务逻辑执行时间减少,吞吐量会大幅下降。
  • GC停顿过长:吞吐量优先的系统往往不在乎GC停顿的长度,然而如果GC停顿过长,GC本身占用的CPU资源可能过多,间接影响吞吐量。
  • 选择不合适的GC策略:不同的垃圾回收器对于吞吐量的影响不同。比如,Parallel GC优先优化吞吐量,但可能会导致较长的GC停顿,而G1则可以在较短的停顿时间内保证较高的吞吐量。

优化吞吐量的手段

  • 选择吞吐量优化的GC:例如,Parallel GC是为吞吐量优化的GC收集器,它会尽量减少GC的停顿时间,换取更高的吞吐量。
  • 调整内存分配:增加堆的总内存、优化各代内存的分配,减少GC的频率。
  • 优化内存使用:减少内存碎片,优化对象的生命周期管理,避免不必要的对象创建。

(二)SLA与实际业务需求的结合

SLA(Service Level Agreement) 是与客户达成的服务水平协议,其中包括了服务响应时间、可用性、吞吐量等要求。在GC优化时,SLA通常包括了对延迟吞吐量的要求,而这些要求需要与应用的实际业务需求紧密结合。

延迟优先的系统往往要求较短的GC停顿时间,以保证实时性和用户体验;而吞吐量优先的系统则关注业务处理能力,尽量减少GC时间占比。

1.如何结合SLA和GC性能

目前各大互联网公司的系统基本都更追求低延时,避免一次 GC 停顿的时间过长对用户体验造成损失,衡量指标需要结合一下应用服务的 SLA,主要如下两点来判断:

简而言之,即为一次停顿的时间不超过应用服务的 TP9999,GC 的吞吐量不小于 99.99%。举个例子,假设某个服务 A 的 TP9999 为 80 ms,平均 GC 停顿为 30 ms,那么该服务的最大停顿时间最好不要超过 80 ms,GC 频次控制在 5 min 以上一次。如果满足不了,那就需要调优或者通过更多资源来进行并联冗余。(大家可以先停下来,看看监控平台上面的 gc.meantime 分钟级别指标,如果超过了 6 ms 那单机 GC 吞吐量就达不到 4 个 9 了。)

通过监控工具(如JVM的gc.meantime指标),可以实时查看GC的平均停顿时间。超过6ms的停顿,可能导致吞吐量达不到四个9(99.99%)的目标。

如果停顿时间较长,可以考虑:

  • 增加资源:通过提升机器的硬件资源(CPU、内存)来分担GC的压力,或采用多机并联冗余,确保服务的高可用性。
  • 调优GC策略:如选择更合适的GC算法(例如,ZGC和Shenandoah等都对低延迟要求的应用效果较好),以及优化内存管理策略(如调整堆大小,控制GC发生的频率等)。

2.SLA与实际业务需求的平衡

有些应用可能在吞吐量和延迟上有不同的侧重点。比如,在线游戏系统可能更关注低延迟,而数据分析系统则更关注吞吐量。在这种情况下,GC的配置需要根据具体的SLA要求,选择合适的GC策略,并做出合适的优化。

如果在实际的业务场景中,吞吐量和延迟两者有矛盾,比如某个系统要求每次GC停顿不超过50ms,但系统又需要处理大量的并发请求,这时就需要综合考虑内存的分配、GC的策略和优化方式,达到SLA要求的平衡。

三、GC Cause 与触发

JVM垃圾回收(GC)的触发条件是复杂且多样的,了解这些触发原因是优化GC性能、避免不必要的GC停顿、提高系统稳定性的关键。

JVM垃圾回收(GC)的触发条件是复杂且多样的,了解这些触发原因是优化GC性能、避免不必要的GC停顿、提高系统稳定性的关键。GCCause类定义了GC操作的多种触发原因(称为GC Cause)。这些触发原因决定了在什么情况下JVM会执行GC操作。要理解这些原因,需要参考HotSpot的源代码中定义的gcCause.hppgcCause.cpp文件。

(一)GCCause 类概述常见触发原因

GCCause 类包含一个枚举类型 Cause,它表示JVM在运行时可能遇到的多种GC触发条件。这些条件分为以下几类,涵盖了从开发人员手动触发到JVM自动触发的各种情境。

// src/share/vm/gc/shared/gcCause.hpp
enum Cause {_java_lang_system_gc,         // System.gc() 调用_full_gc_alot,                // 频繁发生 Full GC_scavenge_alot,               // 频繁发生 Young GC_allocation_profiler,         // 内存分配剖析_jvmti_force_gc,              // 通过 JVM TI 强制 GC_gc_locker,                   // GC 锁定触发_heap_inspection,             // 堆检查触发的 GC_heap_dump,                   // 堆转储触发的 GC_wb_young_gc,                 // 白盒工具触发的 Young GC_wb_conc_mark,                // 白盒工具触发的并发标记_wb_full_gc,                  // 白盒工具触发的 Full GC_no_gc,                       // 没有发生 GC_allocation_failure,          // 分配失败触发的 GC_tenured_generation_full,     // 老年代内存已满_metadata_GC_threshold,       // 元数据 GC 阈值触发_metadata_GC_clear_soft_refs,// 清除软引用触发的 GC_cms_generation_full,         // CMS 回收器的老年代已满_cms_initial_mark,            // CMS 初始标记_cms_final_remark,            // CMS 最终标记_cms_concurrent_mark,         // CMS 并发标记_old_generation_expanded_on_last_scavenge, // 老年代扩展触发_old_generation_too_full_to_scavenge, // 老年代满无法进行年轻代回收_adaptive_size_policy,        // 自适应大小策略_g1_inc_collection_pause,    // G1 增量垃圾回收暂停_g1_humongous_allocation,    // G1 巨型对象分配_dcmd_gc_run,                // 诊断命令触发的 GC_last_gc_cause,              // 非法值,表示上次GC的非法原因
};

1.手动触发GC

  • System.gc(): 通过调用System.gc()显式请求进行GC。
  • JvmtiEnv ForceGarbageCollection: 通过JVM TI(JVM工具接口)强制触发GC。
  • Diagnostic Command: 通过诊断命令(如jcmd)手动触发GC。

2.垃圾回收频率过高

  • FullGCAlot: 发生频繁的Full GC,可能是由于内存压力过大或者GC策略不当。
  • ScavengeAlot: 发生频繁的Young GC(即垃圾回收器专门回收年轻代),可能是由于分配频繁或内存使用不均。

3.内存分配相关

  • Allocation Failure: JVM在分配对象时发现内存不足,无法满足内存分配需求,触发GC。
  • Tenured Generation Full: 如果老年代(Tenured Generation)内存满了,也会触发GC。
  • Old Generation Too Full To Scavenge: 如果老年代无法回收足够的空间,触发GC。
  • G1 Humongous Allocation: 在G1收集器中,出现了“大对象”分配(humongous allocation),即大于一定阈值的对象,这会导致GC触发。

4.JVM内部的GC策略与调整

  • Heap Inspection Initiated GC: JVM进行堆检查时触发GC。
  • Heap Dump Initiated GC: 在生成堆转储时触发GC。
  • Ergonomics: 当JVM的自适应大小调整策略(Ergonomics)认为堆大小需要调整时,可能会触发GC。
  • Metadata GC Threshold: 元数据区域的GC阈值被触发,进行内存回收。

5.CMS(Concurrent Mark-Sweep)收集器相关

  • CMS Generation Full: 如果CMS回收器的某个代(例如老年代)已满,触发Full GC。
  • CMS Initial Mark, CMS Final Remark, CMS Concurrent Mark: 在CMS回收的各个阶段,例如初始化标记、最终标记、并发标记时,都会触发GC。

6.G1(Garbage First)垃圾回收器相关

  • G1 Evacuation Pause: 在G1回收器中,当进行对象搬迁(Evacuation)时,触发的暂停。
  • G1 Inc Collection Pause: 在G1回收器中进行增量垃圾回收时的暂停。

7.白盒(WhiteBox)工具触发的GC

  • WhiteBox Initiated Young GC: 通过白盒工具手动触发的Young GC。
  • WhiteBox Initiated Concurrent Mark: 通过白盒工具触发的并发标记。
  • WhiteBox Initiated Full GC: 通过白盒工具触发的Full GC。

8.其他

  • No GC: 当没有GC操作发生时,表示当前没有触发GC。
  • ILLEGAL VALUE: 这个值是非法的,表示GCCause值未正确设置。

(二)GCCause::to_string 方法解析

GCCause::to_string 方法用于根据传入的 Cause 枚举值返回相应的字符串描述。这个方法通过switch语句,将不同的GC触发原因转换为易于理解的字符串,以便日志记录、调试和性能分析。它能帮助开发人员或运维人员快速识别GC的触发来源,进而进行针对性的优化。

// src/share/vm/gc/shared/gcCause.cpp
const char* GCCause::to_string(GCCause::Cause cause) {switch (cause) {case _java_lang_system_gc:return "System.gc()";case _full_gc_alot:return "FullGCAlot";case _scavenge_alot:return "ScavengeAlot";case _allocation_profiler:return "Allocation Profiler";case _jvmti_force_gc:return "JvmtiEnv ForceGarbageCollection";case _gc_locker:return "GCLocker Initiated GC";case _heap_inspection:return "Heap Inspection Initiated GC";case _heap_dump:return "Heap Dump Initiated GC";case _wb_young_gc:return "WhiteBox Initiated Young GC";case _wb_conc_mark:return "WhiteBox Initiated Concurrent Mark";case _wb_full_gc:return "WhiteBox Initiated Full GC";case _no_gc:return "No GC";case _allocation_failure:return "Allocation Failure";case _tenured_generation_full:return "Tenured Generation Full";case _metadata_GC_threshold:return "Metadata GC Threshold";case _metadata_GC_clear_soft_refs:return "Metadata GC Clear Soft References";case _cms_generation_full:return "CMS Generation Full";case _cms_initial_mark:return "CMS Initial Mark";case _cms_final_remark:return "CMS Final Remark";case _cms_concurrent_mark:return "CMS Concurrent Mark";case _old_generation_expanded_on_last_scavenge:return "Old Generation Expanded On Last Scavenge";case _old_generation_too_full_to_scavenge:return "Old Generation Too Full To Scavenge";case _adaptive_size_policy:return "Ergonomics";case _g1_inc_collection_pause:return "G1 Evacuation Pause";case _g1_humongous_allocation:return "G1 Humongous Allocation";case _dcmd_gc_run:return "Diagnostic Command";case _last_gc_cause:return "ILLEGAL VALUE - last gc cause - ILLEGAL VALUE";default:return "unknown GCCause";}
}

在这个方法中,GCCause::Cause 枚举值被映射成了字符串描述。例如,_allocation_failure 对应 "Allocation Failure"_g1_humongous_allocation 对应 "G1 Humongous Allocation"

(三) GC触发逻辑的关键代码

在JVM中,GCCause 的触发通常发生在垃圾回收器的核心代码部分。具体而言,GC触发逻辑通常与内存分配失败、堆空间不足、GC策略等因素结合。在HotSpot实现中,GC触发的具体调用通常由以下方法来完成:

  • Universe::gc(): 这是触发GC的核心方法。它会根据不同的GC策略和触发条件(如内存分配失败)选择执行合适的垃圾回收。
  • CollectorPolicy::do_collection(): 这是垃圾回收器策略中执行GC的方法,具体触发哪个GC(如Young GC、Full GC)由此决定。

(四)如何根据 GCCause 优化GC策略?

理解不同的GC触发原因之后,开发人员和运维人员可以更有针对性地进行GC调优,如:

  • 内存分配失败(Allocation Failure):如果GC被触发的原因是内存分配失败,可能需要增加堆内存或调整JVM参数来优化内存管理。
  • 频繁的Full GC:如果系统出现FullGCAlot,通常是由于内存泄漏或内存分配策略不当,需要检查应用的内存使用情况,特别是老年代的内存是否过大,是否存在长期存活的对象。
  • G1垃圾回收器触发的GC:如果G1 Evacuation PauseG1 Inc Collection Pause频繁发生,可能需要调整G1的暂停目标时间,或者进一步调整堆的大小、年轻代与老年代的比例。
  • 自适应大小策略(Ergonomics):如果GC因自适应大小策略触发,可以考虑通过手动调整堆大小参数,避免JVM自动调整带来的负面影响。

GCCause类的作用是帮助JVM系统判断垃圾回收的触发条件,理解这些原因对于优化GC行为至关重要。通过分析GC触发原因,开发人员和运维人员能够识别GC的根本原因并采取针对性的优化措施。每种GC触发原因背后都蕴含着系统运行的不同表现和潜在问题,深入理解这些原因能够帮助我们更好地掌握JVM性能优化。

四、判断GC问题是否是根因

在诊断GC问题时,我们常常需要通过多种方法来确认GC是否为根本原因,以及具体的问题在哪里,一般有四种常见的分析方法:时序分析概率分析实验分析、和反证分析。每种方法都能帮助我们更好地理解GC问题的本质。

(一)时序分析:事件发生的时间顺序

时序分析的核心思想是通过对事件发生的时间顺序进行分析,找出GC与系统性能问题之间的关系。在JVM中,GC通常会导致系统响应延迟或暂停,因此我们需要了解GC是否与性能下降的时刻发生关联。

1.基本步骤

  • 日志查看:首先,我们需要查看GC日志和系统的性能日志。GC日志中通常会记录每次GC的开始和结束时间,以及GC的持续时间。
  • 时间戳对比:通过将GC日志和应用日志(比如请求响应时间、吞吐量等)进行时间戳对比,检查GC是否与性能问题的发生时刻一致。如果GC的执行时间和性能问题(如响应延迟)恰好重合,可能说明GC是导致问题的根因。

示例:假设在某些情况下,系统响应时间突增,查看GC日志可以发现,GC暂停时间与响应时间增长几乎完全一致。通过时序分析,我们可以初步怀疑GC造成了响应延迟。

2.关键点

  • 看清GC的暂停时间和应用的瓶颈是否重合。
  • 了解GC的频率和间隔,判断是否在短时间内发生了过多的GC。

(二)概率分析:历史问题的参考

概率分析的基本思路是通过分析历史问题的发生频率,找出是否GC在不同情况下经常成为问题的根源。这是一种基于历史数据的统计分析方法。

1.基本步骤

  • 收集历史数据:分析过去发生过的GC性能问题。查看GC日志、系统监控数据(如堆使用率、GC时间、吞吐量)和应用的性能日志。
  • 统计问题模式:通过统计分析,找出GC发生前后系统性能下降的模式,查看是否每次GC都会导致性能问题,或者某些类型的GC(如Full GC)特别容易导致性能下降。

示例:假设我们有历史的GC数据,发现每次Full GC的暂停时间超过了500ms,而系统的响应时间通常在Full GC之后显著下降,且这种情况时常发生。通过概率分析,我们可以得出结论,Full GC确实是导致性能问题的主要原因。

2.关键点

  • 从历史GC数据中总结哪些GC类型(如Full GCYoung GC)常常导致性能问题。
  • 计算GC暂停时间的统计数据(比如平均暂停时间、最小最大暂停时间),以评估GC的影响。

(三)实验分析:通过模拟验证假设

实验分析是一种通过模拟和验证假设来找出GC问题根因的方法。它通过隔离问题并进行假设验证,帮助确认GC是否为性能问题的根本原因。

1.基本步骤

  • 设置对比实验:在测试环境中,通过调整GC参数或内存配置,模拟不同类型的GC行为。例如,可以调整堆大小、改变垃圾回收器(如G1、CMS、ParallelGC)或者增加GC频率。
  • 验证假设:通过这些实验验证是否GC行为的改变能够影响系统的性能,进而确认是否GC是导致问题的根因。

示例:我们可以在测试环境中,模拟不同的GC策略(例如从G1切换到ParallelGC),并监测GC暂停时间与应用性能的变化。如果发现更换GC策略后,GC暂停时间明显降低,而系统性能有所改善,就可以确认GC是性能问题的根本原因。

2.关键点

  • 在安全的测试环境中进行实验,确保能够模拟生产环境中的负载。
  • 确认调整GC策略后,系统的性能有显著改善,或GC暂停时间得到有效控制。

(四)反证分析:验证表象与问题的相关性

反证分析是一种通过验证现象与问题之间相关性来排除无关因素的方法。它的核心思想是,通过假设问题不由GC引起,然后验证这种假设是否成立,从而得出GC是否为问题根因的结论。

1.基本步骤

  • 排除GC假设:首先假设GC不是问题的根源,查看是否存在其他原因(如内存泄漏、网络瓶颈、应用代码性能问题等)。
  • 对比性能变化:在不触发GC的情况下,观察性能问题是否依然存在。比如,可以通过手动控制GC的执行,或者临时禁用GC(通过-XX:+DisableExplicitGC选项),然后查看是否还会出现性能瓶颈。

示例:假设我们发现应用响应时间突然增加,我们怀疑是GC导致的,但也有可能是网络瓶颈或数据库查询问题。通过反证分析,我们可以暂时禁用System.gc(),并监测是否还有性能下降的现象。如果禁用GC后性能问题依然存在,那么我们可以排除GC是根因。

2.关键点

  • 通过排除法来验证GC是否是性能问题的原因。
  • 通过控制不同因素(如内存、数据库、网络等)来分析GC与其他潜在问题的相关性。

这四种分析方法各有侧重点,可以从不同角度帮助我们诊断GC问题:

  • 时序分析帮助我们通过事件发生的顺序找到GC与性能问题的相关性。
  • 概率分析通过历史数据的统计来发现GC与性能问题的潜在关联。
  • 实验分析通过模拟不同的GC策略来验证GC是否对性能产生影响。
  • 反证分析则帮助我们通过排除法,验证GC是否真正是根本原因。

通过这些方法的结合,我们能够系统地排查GC问题,并做出合理的优化措施,最终提升系统性能。

五、GC 问题分类导读

理解 GC 的不同问题类型和排查方法是每个 JVM 运维和开发人员必须掌握的技能。分析 GC 问题的类型,如何根据不同的服务场景来分类,以及如何按排查难度进行高效的定位和优化,一直是我们最关心的问题。

(一)Mutator 类型:根据对象存活时间的分布进行分类

Mutator 代表的是应用中创建对象的代码或线程,通常由请求/响应流中的计算、I/O 操作或后台任务等组成。根据对象存活时间的分布,Mutator 主要可以分为两种类型:

1.IO 交互型

选择适当的 GC 策略(如 G1),增加 Young 区内存大小,频繁进行 Minor GC,以确保大部分对象能在年轻代及时回收,避免发生长时间停顿。

  • 场景: 当前互联网中的大部分在线服务,例如 RPC、MQ、HTTP 网关服务等。
  • 特点: 内存需求不高,生成的对象大部分会在短时间内死亡。因为这些服务通常是短期交互(如一次 HTTP 请求),所以创建的对象生命周期很短。

GC 调优: 这类应用的特点是 Young 区 对象多,最适合使用大的 Young 区和频繁的 Minor GC。通过调整 Young 区的大小,可以减少 Old 区的负担和 Full GC 的次数。

2.MEM 计算型

调整 Old 区内存大小、使用合适的垃圾回收器(例如 CMS 或 G1),减少 Full GC 的频率,并通过合适的堆内存管理,确保长期存活对象的回收能够平稳进行。

  • 场景: 包括大规模数据计算(如 Hadoop)、分布式存储(如 HBase、Cassandra)、自建分布式缓存等应用。
  • 特点: 对内存的需求较大,对象生命周期较长。由于这类应用通常处理长期存活的数据,它们需要较大的 Old 区来容纳这些对象。

GC 调优: 对这类应用,需要更大的 Old 区内存,减少 Old 区的 GC 频率,并避免频繁的 Full GC。

这两种类型的 Mutator 在内存分配和回收策略上有很大的差异,因此我们在进行 GC 调优时,首先要明确服务属于哪种类型,从而选择合适的 GC 策略和参数。

(二)GC 问题分类

根据不同的 GC 问题,我们可以对问题进行细化分类,这有助于我们快速定位性能瓶颈:

问题类型描述解决方法
Unexpected GC意外发生的 GC,不应该发生的 GC触发。通常由内存泄漏或内存管理不当引起。调整内存分配和 GC 参数,避免不必要的 GC。
Space Shock由于动态扩容或内存波动引起的空间震荡,导致堆内存无法及时回收,内存分配不均衡。优化堆内存分配策略,避免堆内存扩容过度,或者调整 GC 策略以应对空间波动。
Explicit GC显式调用 GC,例如使用 System.gc(),会强制触发全量 GC,可能会导致系统性能下降。避免在应用代码中显式调用 System.gc(),改为依赖 JVM 自动进行垃圾回收。
Young GC主要回收年轻代的对象,通常称为 Minor GC。频繁发生时,会影响系统的响应时间和吞吐量。调整 Young 区的大小,减少频繁的 Minor GC。增加 Young 区内存,减少垃圾回收的频率。
Full GC对整个堆进行回收,通常需要较长时间,并且会导致较长时间的停顿,影响应用的响应时间。减少 Full GC 的触发,通过合理配置堆内存、优化老年代的存活对象管理,避免老年代压力过大。
MetaSpace OOM元空间(MetaSpace)区域内存不足导致的 OOM(内存溢出),通常发生在类加载过多的情况下。增加 MetaSpace 区的内存配置,或者优化类加载机制,避免过多的类加载。
Direct Memory OOM直接内存(Direct Memory)溢出,通常出现在使用 NIO 或进行大量数据传输时,导致堆外内存不足。优化直接内存的使用,监控 Direct Memory 的分配和回收,避免内存泄漏或过度分配。
JNI 引发 GC 问题使用 JNI 调用本地方法时,可能会产生内存泄漏或不当的内存释放,导致 GC 无法及时回收堆外内存。调试 JNI 调用,确保本地方法正确管理内存,避免本地内存泄漏。

(三)排查难度

GC 问题的排查难度与其常见性有很大关系。问题越常见,解决方案就越容易被找到;而遇到不常见的问题时,可能需要深入源码或调试工具进行诊断。

1.常见问题

  • Young GC 过于频繁,大多数开发者可以通过调整 YoungGen 大小来轻松解决。
  • 通过分析 GC 日志和监控数据,发现 Full GC 触发频繁,并采取相应的参数优化。

2.较复杂问题

  • Old GC 频繁:需要分析是否内存老化,是否是由于对象存活时间过长导致的 Old 区压力。可能需要查看应用的内存使用模式,适当增加 Old 区内存。
  • MetaSpace OOM:这种问题的排查比较复杂,可能需要深入代码和类加载机制进行调试。

3.高难度问题

  • Direct Memory OOMJNI 引发的 GC 问题:这些问题通常涉及底层系统与 Java 交互的细节,可能需要通过 JNI 或直接内存的调试工具进行排查。
  • 内存泄漏和异常的 GC 行为:这些问题可能涉及 JVM 内部的复杂机制,需要通过调试或源码分析来解决。

GC 问题不仅仅是内存回收的问题,更多的是如何理解不同类型的服务需求以及对应的内存管理策略。通过掌握 Mutator 类型的区分GC 问题的分类,我们可以更精确地诊断和优化应用性能。排查难度的提升要求我们具备更深入的 GC 原理理解和调试技巧,从简单的配置优化到复杂的源码级调试,都需要在实践中积累经验。

六、总结

Java垃圾回收(GC)是JVM内存管理的重要组成部分,它通过自动回收不再使用的对象来防止内存泄漏和溢出问题。然而,GC的执行过程往往伴随着应用程序的停顿、吞吐量降低等性能代价。因此,合理的GC优化和配置对系统性能至关重要。

通过本文的讲解,我们深入了解了GC对性能的影响,尤其是其延迟和吞吐量这两个关键指标。GC的暂停时间、吞吐量的平衡、以及对内存管理的优化策略,直接关系到应用系统的稳定性和用户体验。我们探讨了多种常见的GC策略,如Serial GC、Parallel GC、CMS、G1等,每种策略都有其特定的适用场景,选对合适的垃圾回收器和调优策略,能够显著提升系统性能。

同时,GC的触发机制和相关的触发原因(GCCause)也是性能调优中的重点,通过对GC触发原因的深入分析,我们能够找到导致性能瓶颈的根本原因,从而采取针对性的优化措施。

最后,通过时序分析、概率分析、实验分析和反证分析等方法,我们可以更科学地判断GC是否为性能问题的根因,并据此做出有效的解决方案。GC调优并不是一蹴而就的过程,需要持续监控和调整,以满足不断变化的业务需求和性能要求。

总体来说,GC作为自动化的内存管理机制,尽管大大简化了开发者的工作,但也要求我们深入理解其原理、触发条件和性能影响,从而在实际项目中做出合理的配置与优化,确保系统在高并发、高吞吐量、低延迟的环境中稳定运行。

相关文章:

如何有效判断与排查Java GC问题

目录 一、GC的重要性与对性能的影响 (一)GC对性能的影响简要分析 1.GC暂停与应用停顿 2.GC吞吐量与资源利用率 3.GC对内存管理的作用:资源回收 4.GC策略与优化的选择 (二)GC的双刃剑 二、GC性能评价标准 &…...

Ubuntu20.04 在离线机器上安装 NVIDIA Container Toolkit

步骤 1.下载4个安装包 Index of /nvidia-docker/libnvidia-container/stable/ nvidia-container-toolkit-base_1.13.5-1_amd64.deb libnvidia-container1_1.13.5-1_amd64.deb libnvidia-container-tools_1.13.5-1_amd64.deb nvidia-container-toolkit_1.13.5-1_amd64.deb 步…...

【流行病学】Melodi-Presto因果关联工具

title: “[流行病学] Melodi Presto因果关联工具” date: 2022-12-08 lastmod: 2022-12-08 draft: false tags: [“流行病学”,“因果关联工具”] toc: true autoCollapseToc: true 阅读介绍 Melodi-Presto: A fast and agile tool to explore semantic triples derived from …...

Android14 OTA差分包升级报Package is for source build

制作好差分包&#xff0c;使用adb线刷模式验证ota升级&#xff0c;出现E:Package is for source build错误 使用adb方式验证 进入recovery模式 adb reboot recovery稍等一会界面会提示 Now send the package you want to apply to the device with "adb sidelaod <…...

PTA L2一些题目

L2-014 列车调度 - 团体程序设计天梯赛-练习集 样例是怎么来的呢&#xff1f;通过题目我们知道每一条轨道的车牌号必须是依次递减的。那么&#xff0c;我们如果让每条轨道尽可能长就能保证轨道数最少------也就是说&#xff0c;我们要尽可能的找最长降序序列。 但是1e5数据量…...

Harbor端口更改||Harbor端口映射

Harbor端口更改|Harbor端口映射 目标&#xff1a;将端口更改为8930 前言 [rootk8s-node1 harbor]# ls common common.sh docker-compose.yml harbor.v2.5.0.tar.gz harbor.yml harbor.yml.tmpl install.sh LICENSE prepare如上是Harbor的文件目录 更改harbor.yml文件…...

基于STM32的智能家居蓝牙系统(论文+源码)

1总体方案设计 本次基于STM32的智能家居蓝牙系统&#xff0c;其系统总体架构如图2.1所示&#xff0c;采用STM32f103单片机作为控制器&#xff0c;通过DHT11传感器实现温湿度检测&#xff0c;MQ-2烟雾传感器实现烟雾检测&#xff0c;光敏电阻实现光照检测&#xff0c;同时将数据…...

视觉Transformer(DETR)

文章目录 DETR总体流程DETR 中 transformer 结构encoderdecoderObeject Query HEADFFNLOSS正负样本分配 简单的demo不足之处 DETR 是首次将 Transformer结构首次应用到视觉 目标检测中&#xff0c;实现 端到端的目标检测。 传统目标检测路线&#xff08;yolo代表&#xff09…...

Linux下学【MySQL】中如何实现:多表查询(配sql+实操图+案例巩固 通俗易懂版~)

每日激励&#xff1a;“不设限和自我肯定的心态&#xff1a;I can do all things。 — Stephen Curry” 绪论​&#xff1a; 本章是MySQL篇中&#xff0c;非常实用性的篇章&#xff0c;相信在实际工作中对于表的查询&#xff0c;很多时候会涉及多表的查询&#xff0c;在多表查询…...

【Office-Word】如何自动生成中英文目录

1.目录介绍 Word这个自动生成目录非常强大&#xff0c;涉及的功能很琐碎&#xff0c;想要完美的生成目录不仅仅是只会目录这么简单&#xff0c;前后涉及到的大纲级别、目标样式和域代码等操作是比较头疼的。 下面就一步一步开始介绍 2.多级标题级别编号设置 目录想要设置好…...

低代码平台的后端架构设计与核心技术解析

引言&#xff1a;低代码如何颠覆传统后端开发&#xff1f; 在传统开发模式下&#xff0c;一个简单用户管理系统的后端开发需要&#xff1a; 3天数据库设计5天REST API开发2天权限模块对接50个易出错的代码文件 而现代低代码平台通过可视化建模自动化生成&#xff0c;可将开发…...

【微信小程序】每日心情笔记

个人团队的比赛项目&#xff0c;仅供学习交流使用 一、项目基本介绍 1. 项目简介 一款基于微信小程序的轻量化笔记工具&#xff0c;旨在帮助用户通过记录每日心情和事件&#xff0c;更好地管理情绪和生活。用户可以根据日期和心情分类&#xff08;如开心、平静、难过等&#…...

【leetcode hot 100 73】矩阵置零

解法一&#xff1a;&#xff08;使用两个标记变量&#xff09;用矩阵的第一行和第一列代替方法一中的两个标记数组&#xff08;col、row[ ]&#xff1a;第几列、行出现0&#xff09;&#xff0c;以达到 O(1) 的额外空间。 这样会导致原数组的第一行和第一列被修改&#xff0c;…...

【Linux】自定协议和序列化与反序列化

目录 一、序列化与反序列化概念 二、自定协议实现一个加法网络计算器 &#xff08;一&#xff09;TCP如何保证接收方的接收到数据是完整性呢&#xff1f; &#xff08;二&#xff09;自定义协议 &#xff08;三&#xff09;自定义协议的实现 1、基础类 2、序列化与反序列…...

混合专家模型(MoE):高效处理复杂任务的智能架构,DeepSeek性能出色的秘诀

混合专家模型 1. 什么是混合专家模型 混合专家模型&#xff08;Mixture of Experts&#xff0c;简称 MoE&#xff09; 是一种先进的神经网络架构&#xff0c;旨在通过整合多个 专门化的子模型&#xff08;或称为“专家”&#xff09; 的预测来提升整体模型性能。其核心思想是…...

使用 Spring Boot 实现前后端分离的海康威视 SDK 视频监控

使用 Spring Boot 实现前后端分离的海康威视 SDK 视频监控系统&#xff0c;可以分为以下几个步骤&#xff1a; 1. 系统架构设计 前端&#xff1a;使用 Vue.js、React 或 Angular 等前端框架实现用户界面。后端&#xff1a;使用 Spring Boot 提供 RESTful API&#xff0c;负责与…...

C++ 内存序在多线程中的使用

目录 一、内存顺序 二、 指令重排在多线程中的问题 2.1 问题与原因 2.2 解决方案 三、六种内存序 3.1 memory_order_relaxed 3.2 memory_order_consume 3.3 memory_order_acquire 3.4 memory_order_release 3.5 memory_order_acq_rel 3.6 memory_order_seq_cst 一、…...

【MySQL】表的操作

文章目录 &#x1f449;表的操作&#x1f448;创建表查看表修改表删除表 &#x1f449;表的操作&#x1f448; 创建表 create tabletable_name (field1 datatype,field2 datatype,field3 datatype ) character set 字符集 collate 校验规则 engine 存储引擎;说明&#xff1a;…...

【Flink银行反欺诈系统设计方案】3.欺诈的7种场景和架构方案、核心表设计

【Flink银行反欺诈系统设计方案】3.欺诈的7种场景和架构方案、核心表设计 1. **欺诈场景分类与案例说明**1.1 **大额交易欺诈**1.2 **异地交易欺诈**1.3 **高频交易欺诈**1.4 **异常时间交易欺诈**1.5 **账户行为异常**1.6 **设备指纹异常**1.7 **交易金额突变** 2. **普适性软…...

DeepSeek-R1本机部署(VLLM+OpenWebUI)

本文搭建环境 系统&#xff1a;Ubuntu 22.04.4 LTS Python版本&#xff1a;Python 3.10 显卡&#xff1a;RTX 4090D 一、DeepSeek-R1-14b原始模型和q8量化模型 1.从modelscope下载模型 官方原始模型&#xff1a;https://modelscope.cn/models/deepseek-ai/DeepSeek-R1-Di…...

计算机网络软考

1.物理层 1.两个主机之间发送数据的过程 自上而下的封装数据&#xff0c;自下而上的解封装数据&#xff0c;实现数据的传输 2.数据、信号、码元 码元就是数字通信里用来表示信息的基本信号单元。比如在二进制中&#xff0c;用高电平代表 “1”、低电平代表 “0”&#xff0c…...

vscode 查看3d

目录 1. vscode-3d-preview obj查看ok 2. vscode-obj-viewer 没找到这个插件&#xff1a; 3. 3D Viewer for Vscode 查看obj失败 1. vscode-3d-preview obj查看ok 可以查看obj 显示过程&#xff1a;开始是绿屏&#xff0c;过了1到2秒&#xff0c;后来就正常看了。 2. vsc…...

HTML第三节

一.初识CSS 1.CSS定义 A.内部样式表 B.外部样式表 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title&g…...

爬虫去重:数据采集时如何进行去重,及去重优化策略

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 1. 去重的核心思路2. 常见的去重方法2.1 基于集合(Set)的去重2.2 基于布隆过滤器(Bloom Filter)的去重2.3 基于数据库的去重2.4 基于文件存储的去重2.5 基于 Redis 的去重3. 去重的优化策略3.1 URL 规范化3.2 分片去…...

IDEA集成DeepSeek,通过离线安装解决无法安装Proxy AI插件问题

文章目录 引言一、安装Proxy AI1.1 在线安装Proxy AI1.2 离线安装Proxy AI 二、Proxy AI中配置DeepSeek2.1 配置本地部署的DeepSeek&#xff08;Ollama方式&#xff09;2.2 通过第三方服务商提供的API进行配置 三、效果测试 引言 许多开发者尝试通过安装Proxy AI等插件将AI能力…...

【电子基础】运算放大器应用笔记(持续更新)

目录 运放应用1&#xff1a; 运放基础知识同相比例运算放大器计算放大倍数 电压比较器 运放应用2&#xff1a;500W调压器同相比例运算放大器计算放大倍数计算平衡电阻 积分电路 运放应用3&#xff1a;逆变电焊机电压跟随器积分电路 加油站1. 为什么比例运算放大电路要加平衡电阻…...

计算机网络核心知识点:信道容量、OSI模型与调制技术详解

目录 一、信道容量与调制技术 奈奎斯特定理&#xff08;无噪声环境&#xff09; 核心公式&#xff1a; 参数说明&#xff1a; 应用场景&#xff1a; 香农定理&#xff08;有噪声环境&#xff09; 核心公式&#xff1a; 参数说明&#xff1a; 应用场景&#xff1a; 奈奎…...

AI赋能企业协作4-NL2Sql技术路线

1.1 对话即服务的一点思考 在数智化转型的过程中&#xff0c;基于即时通信&#xff08;IM&#xff09;的协作平台正悄然成为企业智能化转型的“新基建”。协作平台天然具备高频交互、实时协同和场景化落地的特性&#xff0c;仿佛是为对话式AI量身定制的试验场——员工在熟悉的聊…...

如何用FFmpeg高效拉流(避坑指南)

FFmpeg作为音视频处理领域的“瑞士军刀”,其拉流功能在直播、监控、流媒体分析等场景中应用广泛。本文从实战角度出发,系统梳理FFmpeg拉流的核心工具链、协议适配技巧及高频踩坑点,助你快速掌握流媒体处理核心技能! 一、FFmpeg拉流工具链全解析 核心工具 ffplay:快速验证…...

面试基础--MySQL SQL 优化深度解析

MySQL SQL 优化深度解析&#xff1a;EXPLAIN、索引优化与分库分表实践 引言 在互联网大厂的高并发场景下&#xff0c;数据库的性能优化是至关重要的。MySQL 作为最流行的关系型数据库之一&#xff0c;SQL 查询的性能直接影响了系统的响应时间和吞吐量。本文将深入探讨 MySQL …...

WebRTC简介

WebRTC简介 WebRTC&#xff08;Web Real-Time Communication&#xff09;是一种支持浏览器之间进行实时音视频通信和数据传输的开放标准和技术。它由Google发起&#xff0c;现已成为W3C和IETF的标准。WebRTC允许开发者在不依赖第三方插件或软件的情况下&#xff0c;直接在网页…...

清北deepseek8本手册

“清北手册”通常是“清华大学和北京大学推出的DeepSeek手册”的简写。近期&#xff0c;随着AI技术的迅速发展&#xff0c;清北两高校陆续发布多本自家的DeepSeek学习手册&#xff0c;助力普通人学习进阶。 清华大学的DeepSeek手册已推出5册&#xff0c;内容丰富全面&#xff0…...

前后分离文件上传案例,前端HTML,后端Net6开发的webapi(完整源代码)下载

文件上传功能在项目开发中非常实用&#xff0c;本案例前端用HTML页面的form表单实现&#xff0c;后端用Net6实现。 前后分离文件上传案例&#xff0c;前端HTML&#xff0c;后端Net6&#xff08;完整源代码&#xff09; 下载链接https://download.csdn.net/download/luckyext/9…...

6.过拟合处理:确保模型泛化能力的实践指南——大模型开发深度学习理论基础

在深度学习开发中&#xff0c;过拟合是一个常见且具有挑战性的问题。当模型在训练集上表现优秀&#xff0c;但在测试集或新数据上性能大幅下降时&#xff0c;就说明模型“记住”了训练数据中的噪声而非学习到泛化规律。本文将从实际开发角度系统讲解如何应对过拟合&#xff0c;…...

六十天前端强化训练之第一天到第七天——综合案例:响应式个人博客项目

欢迎来到编程星辰海的博客讲解 目录 前言回顾 HTML5与CSS3基础 一、知识讲解 1. 项目架构设计&#xff08;语义化HTML&#xff09; 2. 响应式布局系统&#xff08;Flex Grid&#xff09; 3. 样式优先级与组件化设计 4. 完整响应式工作流 二、核心代码示例 完整HTML结…...

java数据结构_再谈String_10

目录 字符串常量池 1. 创建对象的思考 2. 字符串常量池&#xff08;StringTable&#xff09; 3. 再谈String对象创建 字符串常量池 1. 创建对象的思考 下面两种创建String对象的方式相同吗&#xff1f; public static void main(String[] args) {String s1 "hello&…...

MCP:重塑AI与数据交互的新标准

MCP&#xff1a;重塑AI与数据交互的新标准 前言 在人工智能领域&#xff0c;大型语言模型&#xff08;LLM&#xff09;的应用日益广泛&#xff0c;但其与外部数据源和工具的集成却一直面临复杂性和碎片化的挑战。 Anthropic提出的MCP&#xff08;Model Context Protocol&…...

Cursor+Claude3.7实现从原型到app开发

最近在X上看到了一些人在用Claude 3.7 Sonnet生成 app原型图的尝试&#xff0c;受到启发&#xff0c;发现这么先生成不同界面的原型图再让Cursor基于原型图开发app会是很好的尝试。尤其是&#xff0c;你也可以不两步直接生成&#xff0c;而是在过程中更可视化地思考你要生产的原…...

洛谷P1334

题目如下 思路&#xff1a; 每次选择最短的两块木板进行合并&#xff0c;直到只剩下一块木板。使用最小堆&#xff08;优先队列&#xff09;来实现这一过程。使用最小堆&#xff1a; 将所有木板的长度放入最小堆&#xff08;优先队列&#xff09; 每次从堆中取出两块最短的木…...

使用wifi连接手机adb进行调试|不使用数据线adb调试手机|找应用错误日志和操作日志

手机在开发者选项里要开启无线调试 在手机设置中查看WiFi的IP地址 设置 -> WLAN -> 已连接的WiFi -> IP地址 使用手机的IP地址连接 adb connect 192.168.1.12:xxxxx 检查连接状态 adb devices 断开特定设备 adb disconnect 192.168.x.x:xxxxx 断开所有设备 …...

大语言模型中温度参数(Temperature)的核心原理

大语言模型中温度参数&#xff08;Temperature&#xff09;的核心原理是通过调整模型输出的概率分布&#xff0c;控制生成结果的随机性和多样性。以下是其原理的详细说明&#xff1a; 一、定义与核心作用 温度参数是生成式模型&#xff08;如GPT系列&#xff09;中的一个超参数…...

【AIGC】通义万相 2.1 与蓝耘智算:共绘 AIGC 未来绚丽蓝图

一、引言 在人工智能技术迅猛发展的今天&#xff0c;AIGC&#xff08;生成式人工智能内容生成&#xff09;领域正以惊人的速度改变着我们的生活和工作方式。从艺术创作到影视制作&#xff0c;从广告设计到智能客服&#xff0c;AIGC 技术的应用越来越广泛。通义万相 2.1 作为一…...

在Ubuntu上搭建Samba服务,实现与windows之间的文件共享

1.安装samba 首先切换为root账户&#xff0c;就是带#符号的表示当前登录的是root超级用户&#xff1b; su - 如果忘记密码&#xff0c;就输入以下命令修改密码 sudo passwd root 再切换为超级用户 然后进行更新软件列表 sudo apt update sudo apt install samba安装 whe…...

Labview培训案例3: 输出正弦波并采集显示

本案例介绍如何从板卡&#xff08;USB6008&#xff09;的模拟量输出端口输出一个正弦波&#xff0c;然后模拟量输入模块进行采样&#xff0c;然后显示到vi画面的‘波形图’中。 详细代码在&#xff1a;Labview课程3&#xff1a;正弦波输出&采集数据&显示资源-CSDN文库 …...

使用 Deepseek + kimi 快速生成PPT

前言 最近看到好多文章和视频都在说&#xff0c;使用 Deepseek 和 kimi 能快速生成精美的 ppt&#xff0c;毕竟那都是别人说的&#xff0c;只有自己尝试一次才知道结果。 具体操作 第一步&#xff1a;访问 deepseek 我们访问 deepseek &#xff0c;把我们想要输入的内容告诉…...

图解MOE大模型的7个核心问题并探讨DeepSeekMoE的专家机制创新

原文地址:https://newsletter.maartengrootendorst.com/p/a-visual-guide-to-mixture-of-experts #mermaid-svg-FU7YUSIfuXO6EVHa {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-FU7YUSIfuXO6EVHa .error-icon{fill…...

青训营:简易分布式爬虫

一、项目介绍 该项目是一个简易分布式爬虫系统&#xff0c;以分布式思想为基础&#xff0c;通过多节点协作的方式&#xff0c;将大规模的网页抓取任务分解&#xff0c;从而高效、快速地获取网络数据 。 项目地址&#xff1a;https://github.com/yanchengsi/distributed_crawle…...

Scala(Array,List,Set,Map,Tuple,字符串 使用的简单介绍)

目录 Array 不可变数组 ArrayBuffer可变数组 List 不可变列表 ListBuffer 可变列表 Set 集合&#xff08;可变不可变&#xff09; Map映射(可变不可变)(键值对) Tuple 元组 字符串 Array 不可变数组 // Array 数组// scala 中的数组下标是()// scala 中的数组是值…...

fmql之Linux WDT

正点原子第52章。 基础知识 正点原子教程 fmql-dts 代码 APP代码&#xff08;不需要编写驱动代码&#xff09; static int dw_wdt_drv_probe(struct platform_device *pdev) {struct device *dev &pdev->dev;struct watchdog_device *wdd;struct dw_wdt *dw_wdt; …...

IntelliJ IDEA集成MarsCode AI

IntelliJ IDEA集成MarsCode AI IDEA中安装插件 安装完毕之后登录自己的账号 点击链接&#xff0c;注册账号 https://www.marscode.cn/events/s/i5DRGqqo/ 可以选择不同的模型...