java什么时候进行垃圾回收,垃圾回收的执行流程

本文详细介绍了Java垃圾回收机制的工作原理,重点讲述了新生代、老年代及永久代的分配策略,以及不同类型的垃圾回收过程(如Minor GC和Full GC)。通过理解这些概念,可以帮助开发者更好地管理应用程序的内存使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java的垃圾回收分为

三个区域:新生代 老年代 永久代,如下图



一个对象实例化时会看看新生代里的Eden(伊甸园)里面有没有足够的空间

如果有,就不进行垃圾回收,对象直接储存在Eden(伊甸园)里

如果没有就会进行一次minor gc(从新生代空间(包括 Eden 和 Survivor 区域)回收内存)

然后再判断Eden(伊甸园)的内存是否足够

如果不足,就看 Survivor (存活区)的内存是否足够

如果内存足够,把Eden(伊甸园)部分活跃对象保存在存活区,然后再把对象保存在Eden(伊甸园)

如果内存不足够,就像老年代发送请求,查看老年代的内存是否足够

如果足够就将部分存活区的活跃对象存在Tenured(老年代),然后再把Eden(伊甸园)部分活跃对象保存在存活区,最后再把对象保存在Eden(伊甸园)

如果内存不够,就会进行一次full gc(是清理整个堆空间—包括年轻代和老年代),然后再次对Tenured(老年代)内存进行判断,

如果足够就进行上面的步骤,如果还不足就会抛出OutOfMemoryError



GC虽然可以进行内存空间的释放,但同时频繁的GC一定会影响性能,GC发生的频率越低,你的系统就越高效.


<think>我们正在讨论Java G1垃圾回收器触发垃圾回收的条件。根据引用[2],G1垃圾回收器关注最大停顿时间、垃圾回收频率、堆空间利用率和并行性。G1将堆划分为多个区域(Region),并优先回收垃圾最多的区域(Garbage First)。 G1触发垃圾回收的条件包括: 1. **年轻代回收(Young GC)**: - 当Eden区满时,会触发年轻代回收。G1会暂停所有应用线程(Stop-The-World),将Eden区和Survivor区存活的对象复制到新的Survivor区或晋升到老年代。 2. **混合回收(Mixed GC)**: - 当堆内存使用达到一定阈值(由`-XX:InitiatingHeapOccupancyPercent`指定,默认45%)时,G1会启动并发标记周期(Concurrent Marking Cycle)。并发标记完成后,G1会进行混合回收,不仅回收年轻代,还会回收一部分老年代区域(选择垃圾最多的老年代区域回收)。 3. **Full GC**: - 当垃圾回收速度跟不上对象分配速度,导致堆内存不足时,G1会退化为串行Full GC(单线程Stop-The-World回收),这会导致较长的停顿时间。通常发生在并发标记完成前堆已满,或者混合回收期间无法快速释放足够空间时。 4. **外部机制触发**: - 调用`System.gc()`可能会触发垃圾回收(但JVM不保证执行)。 - 其他情况如JVM自身的安全点机制、元空间不足等也可能触发。 注意:G1的目标是满足用户设定的最大停顿时间(`-XX:MaxGCPauseMillis`,默认200ms),因此它会根据预测模型动态调整各区域回收的优先级和回收量。 引用来源: [^1]: 介绍了四种垃圾回收器,包括G1。 [^2]: 提到G1关注最大停顿时间等指标。 [^5]: 提到CMS和G1回收器。 相关问题: 1. G1的并发标记周期是如何工作的? 2. 如何设置G1的最大停顿时间? 3. G1的混合回收与CMS的回收过程有何区别?</think>### Java G1垃圾回收器的触发条件 G1(Garbage-First)垃圾回收器在以下条件会触发垃圾回收: #### 1. **年轻代回收触发条件** - **Eden区空间耗尽** 当新对象无法在Eden区分配时,立即触发**年轻代回收(Young GC)**。此时会: - 暂停所有应用线程(STW) - 将Eden区存活对象复制到Survivor区 - 晋升达到年龄阈值(默认15)的对象到老年代[^1][^5] #### 2. **混合回收触发条件** - **堆内存占用达到阈值(IHOP)** 当老年代占用超过`-XX:InitiatingHeapOccupancyPercent`设定值(默认45%)时,启动**并发标记周期**: ```bash -XX:InitiatingHeapOccupancyPercent=45 # 可调整的IHOP阈值 ``` - 阶段1:初始标记(STW短暂暂停) - 阶段2:并发标记(与应用线程并行) - 阶段3:最终标记(STW) - 阶段4:筛选回收(混合GC)[^2][^5] #### 3. **Full GC触发条件** - **空间不足导致晋升失败** 当年轻代回收时,Survivor区或老年代无法容纳晋升对象 - **并发标记周期未完成时堆已满** 若并发标记完成前堆空间耗尽,触发紧急Full GC(单线程串行回收) - **显式调用`System.gc()`** 但受`-XX:+ExplicitGCInvokesConcurrent`参数影响[^3][^4] #### 4. **其他触发机制** - **元空间不足** 当类元数据占用超过`-XX:MetaspaceSize`(如配置的128MB) - **Humongous对象分配失败** 巨型对象(>50% Region大小)直接进入老年代,可能触发回收 - **基于时间的预测** G1根据`-XX:MaxGCPauseMillis`(默认200ms)动态调整回收时机[^2] --- ### G1回收流程示意图 ```mermaid graph TD A[对象分配] -->|Eden区满| B(Young GC) B -->|存活对象| C{晋升条件} C -->|年龄<15| D[Survivor区] C -->|年龄≥15| E[老年代] F[堆占用>45%] --> G[并发标记周期] G --> H[Mixed GC] I[空间不足] --> J[Full GC] ``` --- ### 优化建议 1. **监控IHOP阈值** 使用`jstat -gcutil`观察老年代占用,调整: ```bash -XX:InitiatingHeapOccupancyPercent=60 # 提高阈值减少混合GC频率 ``` 2. **控制停顿时间** 设置最大可容忍暂停: ```bash -XX:MaxGCPauseMillis=150 # 要求G1在150ms内完成回收 ``` 3. **避免Full GC** 增加堆大小或降低对象分配速率: ```bash -Xmx4g # 扩大堆内存 -XX:G1ReservePercent=15 # 保留更多空间应对突发分配 ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值