Java虚拟机(JVM)的垃圾回收(Garbage Collection, GC)是自动管理内存的重要机制,它负责识别不再使用的对象并释放它们所占用的内存,从而防止内存泄漏。以下是关于JVM垃圾回收的一些核心原理和相关知识点:
1. **引用计数算法**:这是一种简单但不适用于循环引用情况的算法。每个对象都有一个引用计数,每当有新的引用指向该对象,计数加1,当引用失效或删除时,计数减1。当计数为0时,对象被视为垃圾。
2. **标记-清除算法**:分为标记和清除两个阶段。首先标记所有可达对象,然后清除未被标记的对象。此算法会导致内存碎片,影响性能。
3. **复制算法**:将内存分为两部分,每次只使用一半。当一半满时,将存活对象复制到另一半,然后清空已使用的一半。优点是效率高,但需要额外的空间。
4. **标记-整理算法**:结合了标记-清除和复制算法的优点。标记所有存活对象,然后将它们移到内存的一端,清除其余部分。这种方法解决了碎片问题,但仍然需要暂停应用。
5. **增量收集算法**:试图在应用程序运行时分阶段进行垃圾回收,以降低暂停时间。然而,JDK5.0未采用此算法。
6. **分代收集算法**:根据对象的生命周期,将内存分为年轻代、年老代和持久代。年轻代又细分为Eden区和两个Survivor区。新对象在Eden区创建,经过几次垃圾回收后仍然存活的对象会进入年老代,而常驻的对象则存储在持久代。
- **年轻代**:经历一次Scavenge GC后仍存活的对象会转移到Survivor区,然后在下一次GC时可能会再转移到另一个Survivor区,最后进入年老代。
- **年老代**:存放从年轻代存活下来的长期存在的对象。
- **持久代**:存储静态数据,如类和方法。大小可以通过`-XX:MaxPermSize=<N>`进行设置。
7. **GC类型**:
- **Scavenge GC**:主要针对年轻代,清理Eden区和一个Survivor区,存活对象移到另一个Survivor区,然后整理Survivor区。
- **Full GC**:涉及全部堆,包括年轻代、年老代和持久代。应尽量减少Full GC,因为它比Scavenge GC慢得多。
8. **垃圾回收器**:
- **串行收集器**:单线程处理,适合单处理器和小内存环境。
- **并行收集器**:多线程处理年轻代,提高垃圾回收效率,适用于多处理器系统,可使用`-XX:+UseParallelGC`开启。
- **并发收集器**:在应用运行的同时进行垃圾回收,减少停顿时间,如CMS(Concurrent Mark Sweep)和G1(Garbage-First)收集器。
每种垃圾回收器都有其适用场景和优化策略,选择合适的垃圾回收器对于提升JVM性能至关重要。在实际应用中,需要根据系统的具体需求和资源情况,通过JVM参数进行配置,以实现最佳的内存管理。