简介
Java的垃圾回收(Garbage Collection, GC)机制是一种自动内存管理技术,用于自动回收不再使用的对象所占用的内存空间。Java的GC机制减少了程序员手动管理内存的负担,降低了内存泄漏和悬挂指针这类问题的发生概率。Java的GC主要关注堆内存(Heap),因为栈内存(Stack)中的对象生命周期与线程紧密相关,通常随着方法的结束而自动释放。
Java GC的基本概念
1. 对象引用:
在Java中,对象的引用决定了哪些对象是可达的,哪些是不可达的。可达的对象是指从根对象(如静态变量、栈上局部变量、寄存器等)开始,通过引用链可以访问到的对象。不可达的对象则被视为垃圾,可被回收。
2. 分代收集:
Java堆内存被划分为几个不同的区域,最常见的划分是年轻代(Young Generation)和老年代(Old Generation),有的实现还包括永久代或元数据区(Metaspace)。年轻代又进一步分为Eden区和两个Survivor区(通常称为S0和S1)。这种分代的目的是为了更高效地进行垃圾回收,因为不同生命周期的对象可以采用不同的回收策略。
GC算法
Java的垃圾回收器可以实现多种算法,主要包括以下几种:
1. 标记-清除(Mark-Sweep):
首先标记出所有需要回收的对象,在标记完成后统一回收所有被标记的对象。这个过程可能会产生内存碎片。
2. 复制(Copy):
将可用内存分为两块,每次只使用其中一块。当这一块内存用完时,将还存活的对象复制到另一块上面,然后一次性清理掉之前用过的那块内存。这种方法简单高效,但内存利用率不高。
3. 标记-整理(Mark-Compact):
首先进行标记,然后将存活的对象向一端移动,最后清理掉边界外的内存区域。这种方式既解决了碎片化问题,又不需要两倍的内存空间。
4. 分代收集算法:
结合了以上算法的思想,根据对象的生存周期将堆内存分为几代,不同代采用最适合其特点的收集算法。例如,年轻代常用复制算法,因为它对象存活率低;老年代则可能采用标记-清除或标记-整理算法。
常见的GC收集器
1. Serial GC:
单线程收集器,适合客户端或小型应用,它在进行垃圾回收时会暂停所有其他工作线程。
2. Parallel GC(也称作吞吐量优先收集器):
多线程收集器,追求高吞吐量,适用于多核服务器。
3. Concurrent Mark Sweep (CMS) GC:
一种以最小化停顿时间为目标的收集器,适用于对响应时间有严格要求的服务。
4. G1 (Garbage First) GC:
面向服务器的垃圾收集器,它将堆内存分割成多个大小相等的区域,并能预测停顿时间,适用于大型应用。
Java虚拟机(JVM)允许用户通过JVM参数来选择和调整垃圾回收器的类型和行为,以满足不同应用场景的需求。