FGC频繁

1、假如FGC次数增加,达到一小时一次,但是gc之后,内存也立马降下来了;

这说明并没有发生内存泄露;只是新生代的对象过早的进入的老年代;

 

原因 : 

  1. 内存泄漏(代码有问题,对象引用没及时释放,导致对象不能及时回收)
  2. 死循环
  3. 大对象

 

解决办法有

  • 增加年轻代空间,以减少youngGc,这样就不会有对象过早的进入老年代
  • 增加年轻代进入老年代的年代阀值,可以增加到最大的15次
  • 使用G1垃圾回收器,可以触发mixGc  而不触发FullGc
`FGC` 在不同上下文中可能有多种含义,但在编程、系统性能或 Java 开发领域中,**最常见的解释是:** > **FGC = Full GC(Full Garbage Collection)** > > 即“**全局垃圾回收**”,指的是 JVM 中对整个堆内存(包括年轻代、老年代)以及方法区(元空间/永久代)的一次彻底垃圾回收。 --- ## 🔍 什么是 FGC? 在 Java 应用运行过程中,JVM 会自动管理内存。当对象不再被引用时,垃圾收集器(Garbage Collector, GC)就会回收它们占用的内存。 ### 分类: | 类型 | 名称 | 范围 | |------|------|------| | Minor GC | 小型 GC | 仅清理新生代(Young Generation) | | Major GC | 大型 GC | 清理老年代(Old Generation) | | ✅ Full GC | 全局 GC(FGC) | 清理整个堆 + 方法区(Metaspace/PermGen) | --- ## ⚠️ FGC 的特点与影响 | 特点 | 说明 | |------|------| | 🐢 **STW(Stop-The-World)** | 所有应用线程暂停,直到 FGC 完成 | | ⏱️ **耗时较长** | 可能持续几百毫秒到几秒,严重影响响应时间 | | 💥 **频繁发生=危险信号** | 表示内存不足、对象晋升过快、内存泄漏等问题 | --- ## 📊 如何查看 FGC? ### 方法一:通过 JVM 日志(推荐开启) 启动 Java 程序时添加以下参数: ```bash -XX:+PrintGCDetails \ -XX:+PrintGCDateStamps \ -Xloggc:gc.log \ -XX:+UseGCLogFileRotation \ -XX:NumberOfGCLogFiles=5 \ -XX:GCLogFileSize=10M ``` 日志输出示例: ``` 2025-04-05T10:00:00.123+0800: 123.456: [Full GC (Ergonomics) [PSYoungGen: 1024K->0K(2048K)] [ParOldGen: 6789K->6543K(8192K)] 7813K->6543K(10240K), [Metaspace: 3456K->3456K(1056768K)], 1.2345678 secs] [Times: user=1.23 sys=0.01, real=1.24 secs] ``` 关键字段: - `Full GC` → 明确表示这是一次 FGC - `real=1.24 secs` → 停顿了 1.24 秒! --- ### 方法二:使用命令行工具实时监控 #### 1. `jstat` 查看 GC 情况 ```bash # 查找 Java 进程 PID jps -l # 查看 GC 统计(每秒刷新一次) jstat -gcutil <pid> 1000 ``` 输出示例: ``` S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 100.00 78.22 95.12 96.34 92.11 123 2.345 5 6.789 9.134 ``` 👉 关注: - `FGC`: 已发生的 Full GC 次数(这里是 5 次) - `FGCT`: Full GC 总耗时(6.789 秒) - 如果这两个值增长很快 → 出问题了! --- #### 2. `jcmd` 触发手动 GC 或打印信息 ```bash # 打印 VM 概要 jcmd <pid> VM.flags # 打印 GC 信息 jcmd <pid> GC.run # 触发一次 GC(不一定是 Full GC) jcmd <pid> GC.class_histogram # 打印对象直方图(可发现内存泄漏) ``` --- ## 🚩 常见导致 FGC 的原因 | 原因 | 解决方案 | |------|----------| | 老年代空间不足 | 增加 `-Xmx` 内存大小 | | 元空间(Metaspace)溢出 | 增加 `-XX:MaxMetaspaceSize` | | 大对象直接进入老年代 | 优化对象创建逻辑 | | 内存泄漏(如静态集合不断添加) | 使用 MAT 分析 dump 文件 | | System.gc() 被调用 | 添加 `-XX:+DisableExplicitGC` | | Eden 区太小导致频繁 Minor GC 后晋升过多 | 调整新生代比例 `-XX:NewRatio` | --- ## ✅ 如何减少或避免 FGC? ### ✅ JVM 参数优化建议 ```bash # 避免显式调用 System.gc() -XX:+DisableExplicitGC # 设置合理的堆大小 -Xms4g -Xmx4g # 使用 G1 GC(适合大内存、低延迟场景) -XX:+UseG1GC -XX:MaxGCPauseMillis=200 # 控制 Metaspace -XX:MetaspaceSize=256M -XX:MaxMetaspaceSize=512M # 记录 GC 日志用于分析 -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:gc.log ``` --- ## 🛠️ 排查步骤总结 1. **开启 GC 日志** 2. **使用 `jstat` 观察 FGC 频率和耗时** 3. **使用 `jmap` 导出堆转储文件** ```bash jmap -dump:format=b,file=heap.hprof <pid> ``` 4. **用 Eclipse MAT 或 JVisualVM 分析内存泄漏** 5. **定位大对象或未释放资源** --- ## ✅ 示例:判断是否需要报警 ```bash # 如果 FGC 每分钟超过 1 次,就告警! if [ $(jstat -gcutil $PID 1000 2 | tail -1 | awk '{print $10}') -gt 1 ]; then echo "警告:FGC 过于频繁!" fi ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值