显式 GC 的使用:留与去,如何选择?

目录

一、什么是显式 GC?

(一) 垃圾回收的基本原理

(二)显式 GC 方法和行为

1. System.gc() 方法

2. 显式 GC 的行为

(三)显式 GC 的使用场景与风险

1. JVM 如何处理显式 GC

2. 显式 GC 的风险

二、显式 GC 对性能的影响

(一) 全 GC 与 STW

1. Full GC 是如何发生的?

2. STW(Stop-the-World)现象

3. Full GC 的性能开销

(二) 对 DirectByteBuffer 的影响

1. DirectByteBuffer 的垃圾回收问题

2. 显式 GC 的作用:避免内存泄漏

3. 禁用显式 GC 带来的问题

4. 解决方案:显式 GC 与优化参数

三、显式 GC 的争议

(一) 保留 System.gc():避免内存泄漏

1. DirectByteBuffer 和堆外内存的清理

2. 在长期运行的系统中避免资源泄漏

(二) 禁用 System.gc():减少性能损耗

1. 避免频繁的 Full GC 导致的 STW(Stop-the-World)停顿

2. 对 JVM 自适应回收策略的干扰

(三) 额外的 JVM 参数:优化显式 GC 的行为

1. -XX:+ExplicitGCInvokesConcurrent

2. -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses

3. -XX:+UseConcMarkSweepGC 或 -XX:+UseG1GC

四、如何选择:留还是去?

(一) 保留显式 GC 的适用场景

 1. 堆外内存管理需求

2. 需 要频繁类卸载的应用

 3. 长时间运行的服务

(二)禁用显式 GC 的适用场景

1. 高并发、 低延迟要求

2. 现 代垃圾回收器的优化

 3. 避免干扰自适应回收机制

(三) 如何优化显式 GC 以减少性能影响

 1. 启用并发回收

 2. 启用类卸载功能

 3. 使用适合的垃圾回收器

五、小结


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

在 Java 中,System.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博客

深入剖析GC问题:如何有效判断与排查

深入剖析GC问题:如何有效判断与排查_排查java堆中大对象触发gc-CSDN博客

动态扩缩容引发的JVM堆内存震荡调优指南

动态扩缩容引发的JVM堆内存震荡:从原理到实践的GC调优指南
高频面试题汇总JVM高频基本面试问题整理_jvm面试题-CSDN博客

一、什么是显式 GC?

显式 GC(Explicit Garbage Collection),顾名思义,是指由程序员主动触发的垃圾回收过程。在 Java 中,显式 GC 是通过调用 System.gc() 方法来触发的。与 隐式 GC(由 JVM 自动管理的垃圾回收)不同,显式 GC 允许开发者手动干预垃圾回收的时机。

(一) 垃圾回收的基本原理

在 Java 中,垃圾回收器负责自动管理内存,回收不再被使用的对象。Java 堆内存通常分为以下几部分:

  • Young Generation(年轻代):存放新创建的对象。随着对象的生命周期变长,一部分会被晋升到 Old Generation(老年代)。
  • Old Generation(老年代):存放存活时间较长的对象。垃圾回收主要是在这里发生。
  • MetaSpace:存储类元数据等。

JVM 的垃圾回收机制一般采用两种主要策略:

  • Minor GC(年轻代回收):通常在 Young Generation 区域进行。
  • Full GC(全堆回收):对整个堆(包括 Young 和 Old 区)进行回收。

通常,垃圾回收会由 JVM 自动触发,基于内存使用情况和垃圾回收的算法策略来决定。但有时开发者可能希望在特定时机手动触发垃圾回收,尤其是当确定内存压力较大或某些特定对象已经不再使用时。

(二)显式 GC 方法和行为

1. System.gc() 方法

System.gc() 方法是 Java 提供的一种显式触发垃圾回收的手段。调用 System.gc() 后,JVM 会尝试进行垃圾回收,尽管它并不一定立刻执行。具体执行什么类型的垃圾回收(如 Minor GC 或 Full GC)取决于 JVM 的实现和内存状态。

System.gc();

2. 显式 GC 的行为

调用 System.gc() 后,JVM 会进入垃圾回收的流程,但实际的执行行为可能有一些不同。具体来说,JVM 会根据当前的内存状态和 GC 策略,决定是否进行一次 Minor GC(年轻代回收)或者 Full GC(整个堆的回收)。例如,在使用 CMS GCG1 GC 时,调用 System.gc() 会触发一个 Full GC,即对整个堆的回收。

需要注意的是,显式调用 System.gc() 并不保证回收一定会发生,它只是建议 JVM 尝试进行垃圾回收。实际执行与否,取决于 JVM 当前的状态、堆内存的使用情况以及系统资源。

(三)显式 GC 的使用场景与风险

显式 GC 一般用于以下几种场景:

  1. 内存泄漏的防范:如果某些对象(如 DirectByteBuffer)未能及时释放其堆外内存资源,开发者可以通过显式调用 System.gc() 来强制回收这些对象。
  2. 内存碎片化:在长时间运行的应用程序中,内存可能出现碎片化现象,显式 GC 可以帮助回收内存,尤其是在 Full GC 执行时,有可能通过压缩堆内存来减少碎片。
  3. 性能调优:在某些特定场景下(如高负载、内存压力大的时候),显式 GC 可能有助于提前清理无用对象,释放内存资源,从而避免由于内存不足导致的其他问题。

不过,需要注意的是,频繁调用显式 GC 可能会导致不必要的性能损耗,特别是在 STW(Stop-the-World) 阶段,应用的线程会被暂停,影响应用的响应能力。

1. JVM 如何处理显式 GC

JVM 提供了若干参数来控制显式 GC 的行为。例如:

  • -XX:+DisableExplicitGC:禁用显式 GC,任何显式调用 System.gc() 将不起作用。这个参数可以防止开发者误用 System.gc(),导致频繁的垃圾回收。
  • -XX:+ExplicitGCInvokesConcurrent:修改 System.gc() 的行为,使其不会触发 Full GC,而是执行并发垃圾回收,从而减少 STW 时间。
  • -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses:不仅执行并发垃圾回收,还会尝试卸载类。

显式 GC 在 JVM 中的处理方式,通常是调用 Universe::heap()->collect(),该方法会触发垃圾回收,并执行整个堆的扫描。

2. 显式 GC 的风险

虽然 System.gc() 看似可以在需要时解决内存问题,但频繁调用显式 GC 会导致以下风险:

  • 性能下降:频繁的 GC 操作会导致应用线程暂停,尤其是 Full GC,这会显著影响应用的响应时间和吞吐量。
  • 内存管理问题:显式 GC 可能会错过 JVM 自动管理的最佳时机,导致垃圾回收在不合适的时机发生,进而影响系统的稳定性和性能。

因此,显式 GC 应该谨慎使用,尤其是在高负载和高并发的应用中。

二、显式 GC 对性能的影响

显式调用 System.gc() 会导致 JVM 触发垃圾回收,而这种操作对系统的性能有着直接的影响,尤其是当它触发 Full GC 时。理解其影响对于性能调优非常重要。

(一) 全 GC 与 STW

1. Full GC 是如何发生的?

在 JVM 中,Full GC 是指对整个堆内存(包括 Young GenerationOld Generation)的回收。这通常发生在以下几种情况:

  • 老年代(Old Generation)内存不足,需要回收。
  • Major GC 触发时,整个堆内存都会被扫描。
  • 显式调用 System.gc() 时,JVM 会进行 Full GC,强制进行整个堆的回收。

Full GC 会涉及到对整个堆的扫描、标记和清理。由于涉及到的内存区域广泛且清理过程复杂,Full GC 的执行代价较高,尤其是在 老年代 存在大量数据时。

2. STW(Stop-the-World)现象

STW(Stop-the-World) 是指在执行垃圾回收期间,所有的应用线程都会被暂停。无论是 Minor GC 还是 Full GC,都可能涉及 STW,但 Full GC 的影响尤其明显。

  • Minor GC:只会回收年轻代,通常比较轻量,停顿时间较短。
  • Full GC:不仅会回收年轻代,还会回收老年代,并进行压缩等操作。其回收的范围和操作都比较复杂,导致停顿时间较长。

由于 Full GC 涉及到全堆回收,JVM 需要将所有应用线程暂停,并进行内存清理和压缩。停顿时间的长短取决于堆内存的大小、JVM 配置以及垃圾回收的效率。在堆内存较大的情况下,Full GC 的停顿时间可能会非常显著,这对高并发、高响应要求的系统来说,可能带来严重的性能问题。

3. Full GC 的性能开销

  • 性能下降:每次执行 Full GC,应用线程必须被完全暂停,垃圾回收的执行期间无法处理业务逻辑。因此,Full GC 可能会导致用户请求的长时间阻塞,从而影响应用的响应时间和吞吐量。尤其是在高并发或低延迟的系统中,频繁的 Full GC 会让系统的性能大幅下降。
  • 内存碎片化:Full GC 还可能引发内存碎片问题,特别是在采用 CMS GCG1 GC 的情况下。回收过程中的内存压缩操作可能导致堆内存碎片化,从而影响内存的分配效率,进而影响系统的整体性能。

因此,频繁的显式 GC 调用尤其是在系统负载较高时,应该尽量避免,以减少 STW 时间,提升系统的响应能力。

(二) 对 DirectByteBuffer 的影响

DirectByteBuffer 是一种特殊的内存管理机制,使用的是 堆外内存(Native Memory),也称为直接内存。它允许 Java 程序直接与操作系统的内存交互,从而提高性能,尤其是在进行高性能 I/O 操作时,如使用 NettyNIO 等框架时。

1. DirectByteBuffer 的垃圾回收问题

与堆内存不同,DirectByteBuffer 是基于堆外内存的对象,因此它并不受 JVM 的垃圾回收器直接管理。换句话说,DirectByteBuffer 对象的内存管理并不像普通的 Java 对象那样自动回收,JVM 只会管理堆内存中的对象。

DirectByteBuffer 的回收通常依赖于 JVM 显式触发垃圾回收,因为 JVM 必须通过 Full GC 来释放已经不再使用的堆外内存。当 System.gc() 被调用时,JVM 会强制进行一次 Full GC,从而对所有对象(包括堆外内存)进行清理。

如果显式调用 System.gc() 频繁地发生,那么它将强制触发 Full GC,从而确保已经无用的 DirectByteBuffer 对象的堆外内存得到及时释放。

2. 显式 GC 的作用:避免内存泄漏

由于 DirectByteBuffer 是通过堆外内存进行管理的,JVM 不会像处理普通 Java 对象那样自动处理其内存回收。如果禁用了显式 GC(例如使用了 -XX:+DisableExplicitGC 参数),并且 DirectByteBuffer 对象在长时间未被回收时,它们可能会导致 Native Memory OOM(堆外内存溢出)。

DirectByteBuffer 对象会通过 sun.misc.Cleaner 自动进行清理,该清理器会在对象被 GC 后释放堆外内存。然而,只有在发生 Full GC 时,DirectByteBuffer 的清理工作才会进行,因此频繁的显式调用 System.gc() 会确保堆外内存及时得到清理。

3. 禁用显式 GC 带来的问题

如果禁用显式 GC(通过 -XX:+DisableExplicitGC),JVM 将不再响应 System.gc() 调用。这可能导致以下问题:

  • DirectByteBuffer 的堆外内存泄漏:如果没有触发 Full GC,DirectByteBuffer 的堆外内存就不会被释放,这可能导致堆外内存的不断增加,最终导致 Native Memory OOM(堆外内存溢出)。这种情况通常出现在高负载的 NIO 应用中,尤其是使用大量直接内存的场景下。

  • 内存压力增大:对于依赖堆外内存的应用程序,禁用显式 GC 后,JVM 将不再定期清理这些内存,导致内存压力增大,从而影响系统的稳定性和性能。

4. 解决方案:显式 GC 与优化参数

为了解决显式 GC 带来的问题,特别是在处理 DirectByteBuffer 时,JVM 提供了几个优化参数:

  • -XX:+ExplicitGCInvokesConcurrent:这个参数会让显式调用 System.gc() 时,执行并发垃圾回收,而不是触发 Full GC。通过这种方式,可以减少 STW 的时间,并且执行垃圾回收时,DirectByteBuffer 的清理也会更及时。

  • -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses:这个参数不仅会执行并发回收,还会在回收时卸载类,减少类的加载压力。它对于减少内存占用和提高系统的回收效率有很大帮助。

通过这些优化参数,能够保证 DirectByteBuffer 的清理不至于因为禁用显式 GC 而导致内存泄漏,同时降低 STW 的影响。

三、显式 GC 的争议

显式 GC 的使用一直存在较大的争议,主要是因为它在不同的应用场景中带来的影响各异。显式调用 System.gc() 可以帮助管理堆外内存等资源,但也会带来较大的性能损失,尤其是在高并发、低延迟的系统中。接下来,我们将从保留和禁用显式 GC 两个角度,分析它们各自的利与弊,并介绍一些可以帮助优化显式 GC 行为的 JVM 参数。

(一) 保留 System.gc():避免内存泄漏

显式调用 System.gc() 在某些特定场景下仍然是非常必要的,尤其是在 堆外内存(Direct Memory)的管理上,保留显式 GC 的常见场景:

1. DirectByteBuffer 和堆外内存的清理

DirectByteBuffer 是 Netty 等高性能网络框架广泛使用的一种堆外内存缓冲区。由于堆外内存不受 JVM 垃圾回收机制的直接管理,它需要通过 sun.misc.Cleaner 来进行清理,而这个过程只有在 Full GC 时才能被触发。频繁的显式调用 System.gc() 可以迫使 JVM 进行 Full GC,从而清理这些不再使用的 DirectByteBuffer 对象及其关联的堆外内存。

  • 内存泄漏的风险:如果没有适时清理堆外内存,系统中可能会累积大量的无用 DirectByteBuffer 对象,导致内存泄漏,最终引发 Native Memory OOM(堆外内存溢出)。因此,保留显式 GC 可以在一定程度上避免这种情况,尤其是在涉及到大量 NettyNIO 操作的高并发应用中。

2. 在长期运行的系统中避免资源泄漏

对于长期运行的应用程序,尤其是有大量 DirectByteBuffer 分配和回收的场景,定期触发 Full GC 可以确保堆外内存得到及时释放。在这种情况下,保留 System.gc() 可以作为防止长期资源泄漏的手段。否则,内存泄漏的后果可能会在系统运行一段时间后显现,导致性能严重下降或崩溃。

(二) 禁用 System.gc():减少性能损耗

尽管显式 GC 在某些场景下有其必要性,但它会显著影响应用的性能,尤其是当频繁调用 System.gc() 时。禁用显式 GC 的几个主要原因:

1. 避免频繁的 Full GC 导致的 STW(Stop-the-World)停顿

CMS GCG1 GC 等垃圾回收器中,频繁调用 System.gc() 会触发 Full GC,从而导致应用线程停止(STW)。这种停顿对高并发、低延迟要求的应用尤为致命。特别是在大规模分布式系统或实时系统中,Full GC 的停顿时间可能会导致应用响应时间大幅增加,严重时甚至会导致系统崩溃。

  • 性能损失:频繁的 STW 停顿会显著影响系统的响应性,尤其是对于低延迟要求极高的应用,如高频交易系统、实时数据分析平台等。

2. 对 JVM 自适应回收策略的干扰

JVM 中的垃圾回收器通常具备 自适应 功能,会根据系统的内存使用情况自动调整回收策略。如果频繁调用显式 GC,会干扰这些自适应机制,影响其优化效果。例如,CMS 和 G1 GC 会根据历史的回收效率来动态调整触发 GC 的时机和策略,频繁调用 System.gc() 会导致 JVM 对垃圾回收的自适应调节失效,从而影响性能。

  • 干扰自适应机制:禁用显式 GC 可以确保 JVM 自主选择最佳的垃圾回收时机和策略,避免人为干扰。

(三) 额外的 JVM 参数:优化显式 GC 的行为

为了减少显式 GC 带来的性能损耗,JVM 提供了一些参数可以帮助优化显式 GC 的行为。使用这些参数时,系统可以在触发显式 GC 时,采用更加高效、并发的回收策略,从而减少停顿时间。

1. -XX:+ExplicitGCInvokesConcurrent

该参数会将显式 GC 的回收模式从传统的 Stop-the-World Full GC 改为 并发回收(Concurrent GC)。这样,当 System.gc() 被调用时,JVM 会尝试以并发方式进行垃圾回收,避免所有应用线程被暂停。

  • 优势:并发回收模式能显著减少 STW 停顿时间,尤其适用于对响应时间敏感的应用。
  • 适用场景:适合高并发、低延迟应用,尤其是在需要频繁调用显式 GC 来释放内存的场景下,能够提高系统的吞吐量和响应速度。

2. -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses

这个参数在 -XX:+ExplicitGCInvokesConcurrent 的基础上,进一步增强了类的卸载功能。在 Full GC 的过程中,除了进行并发回收外,还会尝试卸载不再使用的类,释放类加载器的内存占用。

  • 优势:对于一些大型应用,尤其是长时间运行且存在类加载和卸载的场景(如 Web 应用、应用服务器等),这个参数可以帮助回收不再使用的类,减少内存压力。
  • 适用场景:适用于内存占用较大、类加载频繁的应用,尤其是对内存管理要求较高的场景。

3. -XX:+UseConcMarkSweepGC-XX:+UseG1GC

如果决定保留显式 GC,但又希望减少 Full GC 带来的停顿,可以启用 CMS GCG1 GC。这两个垃圾回收器都能提供并发和低停顿的回收方式,尤其是在大内存应用中能够更平滑地进行垃圾回收,避免全量 GC 导致的停顿。

  • 优势:通过并发收集机制,能够减少 GC 时的停顿,并提高系统的吞吐量。
  • 适用场景:适合内存较大、需要平衡吞吐量和响应时间的应用,如大数据处理系统、服务器应用等。

通过合理选择显式 GC 的使用方式和参数,可以在保证内存管理的同时,最大化地减少对性能的影响。

四、如何选择:留还是去?

在显式 GC 的使用中,我们需要根据应用的具体需求、性能目标以及内存管理策略来决定是否保留 System.gc()

(一) 保留显式 GC 的适用场景

虽然显式 GC 带来一定的性能损耗,但在某些场景下,它却是不可或缺的。

 1. 堆外内存管理需求

对于 DirectByteBuffer 等直接内存的使用,JVM 并不会自动管理堆外内存的回收,这意味着这些内存必须由应用程序手动释放。在此类应用中,定期调用 System.gc() 可以强制进行 Full GC,从而清理堆外内存,避免内存泄漏。

  • 典型场景:高性能框架(如 Netty)通常使用堆外内存来减少 GC 压力,这时定期的显式 GC 调用就显得尤为重要。否则,堆外内存的释放可能因没有足够的触发机制而延迟,导致内存泄漏,进而导致 Native Memory OOM(堆外内存溢出)。

2. 需 要频繁类卸载的应用

一些需要频繁加载和卸载类的应用,如长时间运行的 Java Web 应用,可能会遇到类加载器无法及时卸载类的问题。在这些情况下,显式 GC 可以帮助清理不再使用的类,确保内存得到及时回收。

 3. 长时间运行的服务

对于一些长期运行的服务(例如 Web 服务器或后台任务处理系统),显式 GC 可以有效减少由于内存泄漏引起的堆积问题,尤其是在内存长时间未触发 GC 的情况下。

(二)禁用显式 GC 的适用场景

在许多场景中,频繁调用显式 GC 会带来不必要的性能损耗,尤其是在高并发、低延迟要求较高的系统中。

1. 高并发、 低延迟要求

在高并发、低延迟的系统中,显式调用 System.gc() 会引发 Stop-the-World (STW) 停顿,这可能导致响应延迟增加,影响吞吐量。例如,金融交易、实时数据流处理等应用场景对响应时间和吞吐量有严格要求,显式 GC 会中断业务线程,导致停顿时间不可预测。

2. 现 代垃圾回收器的优化

禁用显式 GC 后,JVM 会依赖其内建的垃圾回收机制,如 G1 GCZGC,这些回收器具有自适应的调度和优化策略,能够根据堆内存的使用情况自动调整回收方式,从而减少停顿和提高吞吐量。在大多数现代 JVM 中,这些自动优化机制的效果已经相当优秀,因此禁用显式 GC 可以让 JVM 更好地进行内存回收。

 3. 避免干扰自适应回收机制

频繁调用显式 GC 会干扰 JVM 的自适应回收机制,导致垃圾回收时机的不合理选择,从而降低垃圾回收的效率。禁用显式 GC 可以避免这种干扰,让 JVM 根据实际内存压力来自动选择最合适的回收策略。

(三) 如何优化显式 GC 以减少性能影响

如果你决定保留显式 GC,但又不希望它带来过大的性能损失,可以通过以下几种方式来优化显式 GC 的影响:

 1. 启用并发回收

使用 -XX:+ExplicitGCInvokesConcurrent 参数可以将显式 GC 从全量回收模式改为并发回收模式。这样,即使调用了 System.gc(),JVM 也会尽量在后台并发进行垃圾回收,减少 Stop-the-World 停顿时间。

  • 适用场景:适用于对性能有较高要求的应用,在需要保留显式 GC 的同时,降低 GC 带来的停顿时间,保持系统的响应性。

 2. 启用类卸载功能

使用 -XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses 参数,可以使显式 GC 不仅进行并发回收,还能尝试卸载类,释放类加载器的内存。这个优化对于一些需要频繁加载和卸载类的应用(如微服务架构、容器化应用等)尤其重要,能够有效防止类加载器内存泄漏。

 3. 使用适合的垃圾回收器

现代 JVM 提供了多种垃圾回收器选择,适合不同类型的应用。例如,使用 G1 GCZGC 可以提供低延迟的回收策略。为了提高系统的内存回收效率,可以选择使用这些回收器,并将显式 GC 调用的时机交给 JVM 来决定。

  • G1 GC:适合大规模堆内存和要求低延迟的系统,能够平衡吞吐量和停顿时间。
  • ZGC:专为低延迟需求设计,几乎消除 Stop-the-World 停顿,非常适合对实时性有极高要求的应用。

显式 GC 的使用是否合适,关键在于应用的特点和需求。通过合理选择是否使用显式 GC,结合适当的 JVM 参数优化,能够在不牺牲性能的情况下,确保系统的内存得到高效管理。

五、小结

显式 GC 在特定场景下是不可或缺的,尤其是在需要手动管理堆外内存或确保资源及时回收时。然而,频繁调用 System.gc() 会触发 Full GC,进而导致 Stop-the-World (STW) 停顿,对系统性能产生显著影响。

因此,是否保留显式 GC 需要根据具体的应用需求来判断:

  • 对于高性能、低延迟的系统,频繁的显式 GC 会带来过大的停顿时间,影响系统响应和吞吐量。在这类场景中,禁用显式 GC 更为合适,让 JVM 的自动垃圾回收机制发挥作用,提升系统的稳定性与响应能力。

  • 对于需要精细控制堆外内存(如 DirectByteBuffer)或特定资源回收的应用,保留显式 GC 是必要的。通过显式触发 GC 可以确保这些资源及时回收,防止内存泄漏或堆外内存溢出。此时,可以通过调整 JVM 参数(如 -XX:+ExplicitGCInvokesConcurrent-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses)来减小显式 GC 对性能的影响,确保回收过程高效且不会过度干扰业务。

综上所述,合理配置和使用 System.gc(),结合合适的 JVM 调优策略,才能在性能和内存管理之间找到最优的平衡点。在实际应用中,我们需要根据系统的业务需求、性能目标和资源管理需求做出灵活的选择,避免盲目启用或禁用显式 GC。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2025.03.03(第一天)

1、常见的高危端口号有哪些,并涉及到哪些攻击方式 端口号服务常见攻击方式21FTP匿名登录、文件上传漏洞22SSH暴力破解、密钥泄露、中间人攻击53DNSDNS劫持、DNS缓存投毒、DDoS放大攻击80/443HTTP/HTTPSSQL注入1433MSSQL暴力破解、SQL注入、远程代码执行3306MySQLSQ…

MySQL数据库基本概念

目录 什么是数据库 从软件角度出发 从网络角度出发 MySQL数据库的client端和sever端进程 mysql的client端进程连接sever端进程 mysql配置文件 MySql存储引擎 MySQL的sql语句的分类 数据库 库的操作 创建数据库 不同校验规则对查询的数据的影响 不区分大小写 区…

确保移动设备上机器学习的安全性:挑战与最佳实践

随着企业不断推出更智能、个性化且响应迅速的体验,AI处理能力在移动设备中的普及,促使了机器学习(ML)本地集成的应用和SDK的快速发展。2024年谷歌I/O大会报告中强调了这一趋势,谷歌鼓励开发者在移动应用中使用本地机器…

【Mac】2025-MacOS系统下常用的开发环境配置

早期版本的一个环境搭建参考 1、brew Mac自带终端运行: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" Installation successful!成功后运行三行命令后更新环境(xxx是mac的username&a…

计算机毕业设计SpringBoot+Vue.js美食推荐系统商城(源码+文档+PPT+讲解)

温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…

【Linux网络#14】:数据链路层(以太网 局域网通信 ARP协议 ARP 欺骗 DDos 攻击)

📃个人主页:island1314 🔥个人专栏:Linux—登神长阶 ⛺️ 欢迎关注:👍点赞 👂🏽留言 😍收藏 💞 💞 💞 生活总是不会一帆风顺&#x…

001-码云操作

码云操作 一、配置公钥1.官网地址1.进入 git bash2.查看生成的公钥3.设置到 Gitee4.测试 二、初始化一个项目1.新建仓库 一、配置公钥 方便后续提交代码不用填写密码 1.官网地址 官网地址:https://gitee.com/Git码云教程:https://gitee.com/help/arti…

Android 获取jks的SHA1值:java.io.IOException: Invalid keystore format

命令生成 keytool -list -v -keystore 全路径.jks -alias 别名 -storepass 密码 -keypass 密码 1、遇到 的问题: 通过快捷键 ‘win r’ 启动的小黑框运行上面的命令会出现下面这个错误keytool 错误: java.io.IOException: Invalid keystore format 2、解决问题 …

项目准备(flask+pyhon+MachineLearning)- 1

目录 这是一篇学习笔记 1. 搭建项目 2.前期准备工作 3.创建用户(user)模板 这是一篇学习笔记 目的:用flask快速实现发布有关机器学习的项目,掌握flask框架,机器学习模型的存储和调用。 1. 搭建项目 使用pycharm创建项目,fl…

DeepSeek开源周Day5: 3FS存储系统与AI数据处理新标杆

项目地址: GitHub - deepseek-ai/3FS: A high-performance distributed file system designed to address the challenges of AI training and inference workloads.GitHub - deepseek-ai/smallpond: A lightweight data processing framework built on DuckDB and…

火语言RPA--PDF提取图片

【组件功能】:提取PDF文档指定位置图片 配置预览 配置说明 文件路径 支持T或# 默认FLOW输入项 待提取图片的PDF文件的完整路径。 提取位置 全部、指定页、指定范围3种位置供选择。 PDF文件密码 支持T或# 打开PDF文件的密码。 页码 支持T或# 提取指定页的页…

专业便捷PDF软件,即开即用

PDF文件因其小巧的体积、便捷的分享与存储方式,以及卓越的安全性,已成为学习、企业及各类机构中不可或缺的文件格式。无论是在学术研究、课程资料、商业报告还是合同文件中,PDF都能有效保持原有的格式和布局,确保内容在不同设备和…

LLVM - 编译器前端 - 学习将源文件转换为抽象语法树(二)

一:处理消息 在一个庞大的软件(比如编译器)中,我们不希望将消息字符串分散在各个地方。如果需要修改消息内容或将其翻译成另一种语言,最好将它们集中存放在一个地方!目前缺少的是对消息的集中定义。下面我们看看来如何实现它。 一种简单的方法是,每条消息都有一个 ID(一…

windows安装vue

1、下载nodejs安装包 https://nodejs.cn/download/ 2、安装node 中途记得可以自己改安装路径,其他都是下一步 3、安装完成后检查 node -v :查看nodejs的版本 npm -v :查看npm的版本 4、修改npm默认安装目录与缓存日志目录的位置 在nodejs目…

PyCharm接入本地部署DeepSeek 实现AI编程!【支持windows与linux】

今天尝试在pycharm上接入了本地部署的deepseek,实现了AI编程,体验还是很棒的。下面详细叙述整个安装过程。 本次搭建的框架组合是 DeepSeek-r1:1.5b/7b Pycharm专业版或者社区版 Proxy AI(CodeGPT) 首先了解不同版本的deepsee…

注意力机制详解笔记 Attention is all I donot understand!

注意力机制好奇了太久,QKV知道是什么但是一直没搞懂为什么,这段时间终于眼一闭心一横摁头看了一天视频,3B1B大佬太强了!基于GPT看了三个视频,基本讲的toy model,没有讲“硬核”的如何训练和码代码&#xff…

腾讯云对象存储服务(COS)

腾讯云对象存储服务(COS) 安全、可扩展、低成本的云存储解决方案 腾讯云 对象存储服务(COS,Cloud Object Storage) 是一种高可靠、高性能、可扩展的云存储服务,专为海量非结构化数据(如图片、…

Linux下安装VS Code

Centos 7 https://blog.csdn.net/weixin_63790642/article/details/132927888 安装存储库 sudo rpm --import https://packages.microsoft.com/keys/microsoft.asc密钥 sudo sh -c echo -e "[code]\nnameVisual Studio Code\nbaseurlhttps://packages.microsoft.com/yum…

win32汇编环境,窗口程序中使控件子类化的示例一

;运行效果 ;win32汇编环境,窗口程序中使编辑框控件子类化的示例一 ;窗口子类化,就是把某种控件,自已再打造一遍,加入自已的功能。比如弄个特殊形状的按钮,或只能输入特殊字符的编辑框 ;当然,一般来说,这都是…

数组中的逆序对(C++)

目录 1 问题描述 1.1 输入描述: 1.2 示例1 1.3 示例2 2 解题思路 2.1 暴力解法 2.2 归并排序法 3 代码实现 3.1 暴力解法 3.2 归并排序法 4 代码解析 4.1 暴力解法 4.1.1 初始化 4.1.2 判断是否是逆序对 4.2 归并排序法 4.2.1 InversePairs 主函数 …