调用 System.gc() 的弊端及修复方式

弊端分析
  1. 不可控的执行时机
    System.gc() 仅是 建议 JVM 执行垃圾回收,但 JVM 可自由忽略该请求(尤其是高负载时)。实际回收时机不确定,无法保证内存及时释放。

  2. 严重的性能问题

    • Stop-The-World 停顿:触发 Full GC 时会暂停所有应用线程(可达秒级),导致系统卡顿。

    • 冗余回收:JVM 已有成熟的垃圾回收策略(如分代回收)。手动调用可能打断优化策略,触发不必要的 Full GC,浪费 CPU 资源。

  3. 干扰 JVM 自优化机制
    现代 JVM(如 HotSpot)基于内存分配/回收模式动态调整堆大小和 GC 策略。手动调用 System.gc() 会干扰此过程,降低自适应效率。

  4. 不同 JVM 行为差异

    • 部分 JVM(如 Oracle HotSpot)默认响应 System.gc() 并执行 Full GC。

    • 其他 JVM(如 Azul Zing)可能完全忽略。
      代码可移植性降低。

  5. 掩盖真实内存问题
    开发者可能误用 System.gc() 作为“内存优化”手段,掩盖内存泄漏或设计缺陷,延误根本问题修复。


修复方式与最佳实践
  1. 完全避免显式调用 System.gc()
    原则:99% 的场景无需手动 GC。JVM 的内存管理优于人工干预。
    措施:删除代码中所有 System.gc() 调用。

  2. 通过 JVM 参数禁用显式 GC
    添加启动参数,强制忽略 System.gc() 调用:

    bash

    -XX:+DisableExplicitGC  # 禁止 System.gc() 触发 Full GC

    适用场景:确保遗留代码或第三方库中的调用无效。

  3. 替换为建议式回收(谨慎使用)
    若必须请求回收(如性能测试),使用 轻量级建议

    java

    // Java 9+ 推荐
    java.lang.ref.Reference.reachabilityFence(obj); // 提示 JVM 可回收对象

    java

    // 或仅回收部分区域(JDK 8+)
    java.lang.management.MemoryMXBean bean = ManagementFactory.getMemoryMXBean();
    bean.gc(); // 触发管理接口的 GC(仍不保证执行)
  4. 优化内存使用设计

    • 及时解引用:不再用的大对象显式置 null(如缓存、集合)。

    • 使用弱引用:对缓存场景用 WeakHashMap 或 SoftReference,允许内存不足时自动回收。

    • 分治大对象:拆分大数据块,避免单对象生命周期过长。

  5. 精准监控与调优 GC

    • 启用 GC 日志

      bash

      -Xlog:gc*:file=gc.log:time:filecount=5,filesize=10m
    • 分析工具

      • JDK Mission Control / VisualVM

      • G1 GC 分析器(如 GCViewer)

    • 调优参数示例

      bash

      # G1 GC 优化(JDK 9+)
      -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:G1HeapRegionSize=4m

何时可能“需要”手动 GC?(极少见场景)
  1. 内存敏感测试:测量特定操作后内存占用量。
    方案:在测试中调用 System.gc() 前/后,但需配合 -XX:+DisableExplicitGC 避免生产环境生效。

  2. Native 资源管理:DirectByteBuffer 等堆外内存释放。
    方案:用 sun.misc.Cleaner 或 JDK 14+ 的 MemorySegment 替代手动 GC。


总结

问题解决方案
不可控执行时机删除调用 + JVM 参数禁用
Stop-The-World 停顿优化 GC 参数 + 选择低延迟收集器
干扰 JVM 自优化依赖 JVM 默认策略
掩盖内存泄漏用 Profiler 定位真实问题

核心原则:信任 JVM 的 GC 算法。通过监控、参数调优和代码优化解决内存问题,而非手动调用 System.gc()

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

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

相关文章

git merge 和 git rebase 的区别

主要靠一张图:区别 git merge git checkout feature git merge master此时在feature上git会自动产生一个新的commit 修改的是当前分支 feature。 git rebase git checkout feature git rebase master(在feature分支上执行,修改的是master分支…

Java学习--JVM(2)

JVM提供垃圾回收机制,其也是JVM的核心机制,其主要是实现自动回收不再被引用的对象所占用的内存;对内存进行整理,防止内存碎片化;以及对内存分配配进行管理。JVM 通过两种主要算法判断对象是否可回收:引用计…

用大模型(qwen)提取知识三元组并构建可视化知识图谱:从文本到图谱的完整实现

引言 知识图谱作为一种结构化的知识表示方式,在智能问答、推荐系统、数据分析等领域有着广泛应用。在信息爆炸的时代,如何从非结构化文本中提取有价值的知识并进行结构化展示,是NLP领域的重要任务。知识三元组(Subject-Relation-O…

(附源码)基于 Go 和 gopacket+Fyne 的跨平台网络抓包工具开发实录

基于 Go 和 gopacket Fyne 的跨平台网络抓包工具开发实录 一、项目背景 在网络安全、协议分析、运维排查等场景中,抓包工具是不可或缺的利器。Wireshark 虽然功能强大,但对于部分初学者或有定制需求的开发者来说,学习曲线较陡,且…

Langchain和Faiss搭建本地知识库对比

对比 对比维度及优缺点分析对比维度LangChain(封装 FAISS)直接使用 FAISS易用性✅ 高,提供高级封装,简化开发流程❌ 中等,需要熟悉 FAISS API学习成本✅ 低,适合快速开发❌ 高,需要掌握 FAISS 的…

Java常用命令汇总

JDK 工具命令jps(Java Virtual Machine Process Status Tool)命令示例:jps -l 应用场景:列出当前系统中所有Java进程的PID和主类名,常用于快速定位Java应用的进程ID。javac(Java Compiler)命令示…

Llama 2:开放基础模型与微调聊天模型

温馨提示: 本篇文章已同步至"AI专题精讲" Llama 2:开放基础模型与微调聊天模型 摘要 在本研究中,我们开发并发布了 Llama 2,一组预训练和微调的大型语言模型(LLMs),其规模从 70 亿参…

ThinkPHP 8 在 Apache 下启用伪静态

ThinkPHP 8 在 Apache 下启用伪静态,需要配置 .htaccess 文件并确保 Apache 支持 URL 重写。以下是详细设置步骤:1. 启用 Apache 重写模块首先确保 Apache 的 mod_rewrite 模块已启用。编辑 Apache 配置文件(通常是 /etc/apache2/apache2.con…

Android开发中Retrofit使用方法与底层原理详解

Retrofit 是 Android 开发中一个 类型安全、基于注解、高度解耦 的 RESTful HTTP 客户端库,由 Square 公司开发。它极大地简化了 Android 应用与 Web 服务进行网络交互的过程。 核心价值: 声明式 API 定义: 使用 Java/Kotlin 接口和注解描述 …

基于FPGA的IIC控制EEPROM读写(2)

基于FPGA的IIC控制EEPROM读写 文章目录基于FPGA的IIC控制EEPROM读写一、EEPROM简介二、代码实现——个人理解1、状态机2、仿真效果3、上板验证4、代码top.viic_master.vuart三、代码实现——复用性较高的IIC模块1、框架设计2、状态机设计3、仿真效果4、上板验证5、代码top.viic…

C# 界面程序在23H2型号系统中无法退出

20250716记录 环境:c# winform问题描述:主界面退出直接使用了Environment.Exit(0); 程序假死,无法关闭解决措施://使用 this.Close();以下代码目标:执行完程序自身后,删除指定文件(可用于程序文…

Kafka——集群核心参数配置

引言在分布式系统中,Kafka 凭借其高吞吐量、低延迟和强大的扩展性,成为数据管道和流处理的首选解决方案。然而,要充分发挥 Kafka 的性能和稳定性,正确配置集群参数至关重要。为什么参数配置如此重要?Kafka 的参数配置直…

单臂路由实现VLAN互通实验

实验拓扑图实验需求:按照图示为 PC3 和 PC4 配置 IP 地址和网关PC3 属于 Vlan10,PC4 属于 Vlan20,配置单臂路由实现 Vlan10 和 Vlan20 三层互通PC3 和 PC4 可以互通实验步骤:1.PC 配置 IP 地址2.PC3 属于 Vlan10,PC4 属…

基于渐进式迁移学习网络(PTLN)​的小样本故障诊断模型

目录 一、研究背景与挑战​ ​二、创新方法:渐进式迁移学习网络(PTLN)​​ ​1. 核心架构​编辑 ​2. 训练优化​ 三、核心代码 四、实验结果与优势​ ​1. 数据集​ ​2. 性能对比​ ​3. 关键验证​ 五、工程价值与未来方向​ 六、补充信息​ 一、研究背景与挑…

网络原理 —— HTTP

通过网络初识,我们认识了网络的协议栈,TCP/IP 分为五层:应用层,传输层,网络层,数据链路层,物理层。也介绍了其中的关键协议。而这些协议的理解,是我们写网络代码的基础。 应用层&…

docker--安装--原理

安装 链接 启动之后,docker状态查看: sudo systemctl status docker 添加普通用户到docker用户组: sudo usermod -aG docker $USER# 重启或者使用以下命令刷新组权限:newgrp docker 原理

Java并发第一篇(从零开始:一文读懂Java并发编程核心基础)

从零开始:一文读懂Java并发编程核心基础一. 为什么需要并发编程?二. 并发编程的“另一面”:挑战与代价2.1 频繁的上下文切换2.2 线程安全问题(如:死锁)三. 夯实基础:必须掌握的核心概念与操作3.…

【删库跑路】一次删除pip的所有第三方库

进入命令行,先list看下库存pip list导出所有的第三方库至一文件列表pip freeze >requirements.txt按照列表卸载所有库pip uninstall -r requirements.txt -y再list看下,可见库存已清空

python 【技术面试题和HR面试题】➕列表操作、条件判断、循环、函数定义编程题

1.技术面试题 (1)解释Linux中的进程、线程和守护进程的概念,以及如何管理它们? 答: 进程 概念:程序运行的实例,有独立资源(如内存),是系统调度的基本单位。 管…

Debian 12中利用dpkg命令安装MariaDB 11.8.2

MariaDB 11.8解决了2038问题,即在32位系统中将timestamp从2038-01-19 03:14:07 UTC扩展到2106-02-07 06:28:15 UTC,向后延长了68年。由于写此文时Debian 12的源中还没有MariaDB 11.8,采用源码编译又太费时,可用二进制码或dpkg安装 .下面简要记…