Java垃圾回收详解:GC算法与收集器
Java垃圾回收详解:GC算法与收集器
概述
垃圾回收(Garbage Collection)是JVM自动管理内存的机制。本教程介绍GC算法和常用收集器。
1. 对象存活判断
public class ObjectLifecycleDemo {
// 引用计数法:每个对象有一个引用计数器
// 可达性分析:从GC Roots出发,不可达的对象可以被回收
// GC Roots包括:
// 1. 虚拟机栈中的引用
// 2. 方法区中的静态属性
// 3. 方法区中的常量
// 4. 本地方法栈中的引用
private static Object gcRoot = new Object();
public static void main(String[] args) {
Object obj1 = new Object();
Object obj2 = new Object();
obj1 = null; // obj1可以被回收
// obj2仍然被引用,不能被回收
System.gc(); // 建议进行垃圾回收
}
}
2. GC算法
public class GCAlgorithms {
// 1. 标记-清除算法
// 2. 复制算法
// 3. 标记-整理算法
// 4. 分代收集算法
// 新生代:复制算法
// 老年代:标记-清除或标记-整理算法
public static void main(String[] args) {
// 测试GC算法
// -XX:+UseG1GC -XX:MaxGCPauseMillis=200
}
}
3. 常用GC收集器
public class GCCollectors {
// 1. Serial收集器:单线程,适合客户端
// 2. ParNew收集器:多线程新生代收集器
// 3. Parallel Scavenge收集器:吞吐量优先
// 4. Serial Old收集器:老年代单线程
// 5. CMS收集器:低停顿
// 6. G1收集器:可预测停顿
// G1收集器特点:
// 1. 分区收集
// 2. 可预测停顿
// 3. 空间整合
// 4. 并行与并发
public static void main(String[] args) {
// 查看当前使用的GC收集器
// java -XX:+PrintCommandLineFlags -version
// G1收集器参数
// -XX:+UseG1GC
// -XX:MaxGCPauseMillis=200
// -XX:G1HeapRegionSize=16m
}
}
4. 实际应用示例
内存泄漏检测
import java.util.*;
public class MemoryLeakDemo {
private static List<byte[]> memoryLeak = new ArrayList<>();
public static void main(String[] args) {
// 模拟内存泄漏
for (int i = 0; i < 1000; i++) {
memoryLeak.add(new byte[1024 * 1024]); // 1MB
System.out.println("已分配: " + i + " MB");
}
}
}
GC调优
public class GCTuningDemo {
public static void main(String[] args) {
// GC调优参数
// -Xms512m -Xmx512m // 堆大小
// -XX:NewRatio=2 // 新生代:老年代 = 1:2
// -XX:SurvivorRatio=8 // Eden:Survivor = 8:1
// -XX:+UseG1GC // 使用G1收集器
// -XX:MaxGCPauseMillis=200 // 目标停顿时间
// 监控GC
// jstat -gc <pid> 1000
// jmap -heap <pid>
}
}
5. 最佳实践
- 避免内存泄漏:及时释放不再使用的对象
- 合理设置堆大小:根据应用需求配置
- 选择合适的GC算法:根据应用场景选择
- 监控GC日志:定期分析GC日志
- 使用GC调优工具:jstat、jmap、VisualVM等
总结
垃圾回收是Java内存管理的核心机制。理解GC算法和收集器,可以编写更高效的Java程序。在实际编程中,要合理配置GC参数,避免内存泄漏。