垃圾回收算法概述

  • 引用计数:一个对象被引用计数器加一,取消引用计数器减一,引用计数器为0才能被回收。优点:简单。缺点:不能解决循环引用的问题,比如A引用B,B引用A,但是这两个对象没有被其他任何对象引用,属于垃圾对象,却不能回收;每次引用都会附件一个加减法,影响性能。
  • 标记清除法:分为两个阶段:标记阶段和清除阶段。标记阶段通过根节点标记所有可达对象,清除阶段清除所有不可达对象。缺点:因为清除不可达对象之后剩余的内存不连续,会产生大量内存碎片,不利于大对象的分配。
  • 复制算法:将内存空间分成相同的两块,每次只是用其中的一块,垃圾回收时,将正在使用的内存中的存活对象复制到另外一块空间,然后清除正在使用的内存空间中的所有对象,这种回收算法适用于新生代垃圾回收。优点:垃圾回收对象比较多时需要复制的对象恨少,性能较好;不会存在内存碎片。缺点:将系统内存折半。
  • 标记压缩算法:是一种老年代回收算法,在标记清除的基础上做了一些优化,首先从根节点开始标记所有不可达的对象,然后将所有可达的对象移动到内存的一端,最后清除所有不可达的对象。优点:不用将内存分为两块;不会产生内存碎片。
  • 分代算法:新生代使用复制算法,老生带使用标记清除算法或者标记压缩算法。几乎所有的垃圾回收期都区分新生代和老生带。
  • 分区算法:将整个堆空间分成很多个连续的不同的小空间,每个小空间独立使用,独立回收。为了更好的控制gc停顿时间,可以根据目标停顿时间合理地回收若干个小区间,而不是整个堆空间,从而减少gc停顿时间。
### 常见的垃圾回收算法及其工作原理 #### 1. 标记-清除(Mark-Sweep) 标记-清除算法是最早的垃圾回收算法之一。该算法分为两个阶段: - **标记阶段**:从根节点开始遍历整个对象图,标记所有可达的对象。未被标记的对象被认为是不可达的,即垃圾对象[^2]。 - **清除阶段**:扫描堆内存,释放那些未被标记的对象所占用的空间。 尽管此算法简单有效,但它存在一个问题——容易产生内存碎片,这可能导致后续的大对象分配失败[^4]。 --- #### 2. 标记-复制(Copying) 标记-复制算法将堆分成两部分:From区和To区。每次仅使用其中一个区域存储活动对象,在垃圾回收时,将存活对象复制到另一个区域。 - **优点**:由于每次都清理掉一半的空间,因此不会产生内存碎片;并且复制操作通常较快[^4]。 - **缺点**:需要双倍的内存空间,造成较大的内存浪费,尤其是在存活对象比例较高的情况下表现不佳[^4]。 这种算法常用于新生代的垃圾回收,因为新生代中的大多数对象生命周期较短,死亡率高[^3]。 --- #### 3. 标记-整理(Mark-and-Compact) 为了克服标记-清除算法产生的内存碎片问题,标记-整理算法在完成标记之后,将所有的存活对象向一端移动,从而消除中间的空隙。 - **过程**:先标记所有存活对象,再将其紧凑排列在一起,最后更新指针指向新位置[^4]。 - **特点**:虽然解决了内存碎片问题,但由于涉及大量的数据搬移操作,可能会增加一定的运行开销。 --- #### 4. 分代收集理论(Generational Collection) 分代收集理论基于以下两点观察: - 大多数对象很快就会变得不可访问。 - 少数长期存活的对象倾向于持续更长时间。 基于这些特性,JVM将堆划分为不同的区域(通常是年轻代、老年代和永久代/元空间)。不同代采用不同的垃圾回收策略: - **年轻代**:频繁发生小规模的垃圾回收(Minor GC),常用 Copying 或 Mark-Sweep 算法处理。 - **老年代**:当对象经历多次 Minor GC 后仍未被回收,则进入老年代,这里发生的 Full GC 较少但耗时较长[^3]。 这种方法显著提高了垃圾回收的整体效率[^2]。 --- #### 实现方式概述 各种垃圾回收器根据具体需求选择了适合自己的核心算法组合。例如: - **Serial GC 和 Parallel GC** 主要依赖于传统的 Mark-Sweep/Copying 技术来优化单线程或多线程环境下的性能[^3]。 - **CMS (Concurrent Mark Sweep)** 使用并发机制降低停顿时间,但仍可能面临内存碎片化挑战[^3]。 - **G1/GC/ZGC/Shenandoah** 结合分区技术和先进的压缩技术,进一步改善了大容量堆上的垃圾回收效果[^3]。 ```java // 示例代码展示如何设置特定的垃圾回收器 public class GCTest { public static void main(String[] args) { System.setProperty("java.vm.name", "G1"); Runtime.getRuntime().gc(); // 手动触发垃圾回收 } } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值