Java 的 JVM 垃圾回收机制通过一系列算法和策略来自动管理内存。以下是 JVM 垃圾回收机制的工作原理,以案例来说明其运作。
考虑一个简单的 Java 程序,该程序创建多个对象并模拟内存的使用:
public class GarbageCollectionDemo {
public static void main(String[] args) {
// 创建大量对象
for (int i = 0; i < 10000; i++) {
String temp = new String("Object " + i);
}
// 触发垃圾回收
System.gc();
// 输出当前的内存状态
Runtime runtime = Runtime.getRuntime();
System.out.println("Used memory: " + (runtime.totalMemory() - runtime.freeMemory()));
}
}
垃圾回收机制工作原理
1.对象的分配:
在上面的代码中,new String("Object " + i) 每次循环都会创建一个新的 String 对象,这些对象最初被分配在年轻代(Young Generation)中。
2.标记-清除算法:
.JVM 通过标记-清除算法来管理垃圾回收。它会标记所有仍然可以访问的对象(可达对象),然后清除未标记的对象,释放其占用的内存。
在我们的例子中,随着循环结束,创建的字符串对象变得不可达,等待被回收。
3.分代收集:
3.JVM 将堆内存分为不同的区域:年轻代、老年代和持久代(或元空间)。年轻代用于存放新创建的对象,老年代用于存放存活时间较长的对象。
Minor GC:当年轻代满时,会触发年轻代的垃圾回收(Minor GC),快速清理不可达对象,存活的对象会被移动到老年代。
Major GC:当老年代满时,会进行更复杂的回收(Major GC),这个过程通常比较耗时。
4.自动触发和手动触发:
在程序中,我们通过 System.gc() 手动请求 JVM 进行垃圾回收,但这只是一个建议,JVM 可以选择不执行。
在实际运行中,JVM 会根据内存使用情况自动决定何时进行垃圾回收。
内存状态监控
最后,通过 Runtime.getRuntime() 获取当前内存使用情况,可以看到程序在运行后的内存状态。虽然在 for 循环中创建了大量对象,垃圾回收机制会有效回收不再使用的对象,保持系统的稳定性和效率。