Java虚拟机垃圾回收:让内存管理更高效

Java程序的时候,你有没有遇到过程序跑着跑着突然卡一下?有时候可能不是代码逻辑的问题,而是JVM在默默做一件事——垃圾回收

什么是Java虚拟机垃圾回收

Java不用手动释放内存,这得益于JVM的垃圾回收机制。简单说,就是系统自动识别哪些对象已经用不到了,然后把它们占的内存清理掉,腾出空间给新对象使用。

就像你家里的垃圾桶,用久了会满,系统得定时去清空。只不过JVM这个“清洁工”更智能,它能判断哪些是真垃圾,哪些还能再利用。

常见的垃圾回收器有哪些

JVM提供了几种不同的垃圾回收器,适应不同场景。比如:

  • Serial GC:适合单核机器,简单粗暴,停顿明显
  • Parallel GC:多线程回收,吞吐量高,适合后台服务
  • CMS(Concurrent Mark Sweep):尽量减少停顿,适合对响应时间敏感的应用
  • G1 GC:兼顾吞吐和延迟,现代应用常用

现在的项目大多用G1,比如电商平台的订单系统,不能因为回收垃圾导致用户下单卡住几秒。

对象是怎么被判定为“垃圾”的

JVM通过“可达性分析”来判断对象是否存活。从一些根对象(如栈中的局部变量、静态变量)出发,能被引用到的就是活着的,反之就是垃圾。

举个例子:你之前借了朋友一本书,后来换手机号搬了家,朋友找不到你了,这本书就算“失联”了。JVM也一样,找不到引用路径的对象,就标记为可回收。

代码里也能影响垃圾回收

虽然GC是自动的,但代码写法会影响它的效率。比如下面这段:

for (int i = 0; i < 1000000; i++) {
List<String> temp = new ArrayList<>();
temp.add("临时数据" + i);
// 没有外部引用,很快会被回收
}

每次循环都创建新对象,很快就会触发年轻代GC。如果改成复用或者控制生命周期,就能减轻GC压力。

还有种情况,明明想释放资源,却因为静态集合一直持有引用,导致内存越积越多。这种叫内存泄漏,GC也救不了。

如何查看GC情况

启动Java程序时加几个参数,就能看到GC日志:

-XX:+PrintGC -XX:+PrintGCDetails -Xloggc:gc.log

日志里会显示每次回收花了多久,堆内存变化情况。结合工具如VisualVM或GCViewer,能直观看出是否存在频繁回收或长时间停顿。

上线前做一次压测,看看GC表现,比线上出问题再查要强得多。

理解JVM垃圾回收,不只是为了调优,更是为了让程序跑得更稳。别等到用户抱怨“怎么又卡了”,才想起去看看GC日志。