java中对象由jvm垃圾回收器自动回收,类一般不销毁;对象不可达(无法从gc roots到达)时才可能被回收,置null不保证立即回收;类卸载仅发生在类加载器被回收等极少数场景。

Java 中类与对象的销毁不是由开发者手动控制的,而是由 JVM 的垃圾回收机制(GC)自动完成。关键要分清:对象可以被回收,而类本身一般不会“销毁”,除非其所在的类加载器被卸载。
对象什么时候会被回收
对象是否可回收,取决于它是否还“可达”。JVM 使用可达性分析算法,从一组称为 GC Roots 的对象出发,沿着引用链向下搜索:
- 虚拟机栈中正在使用的局部变量引用的对象
- 方法区中静态变量(static 字段)引用的对象
- 方法区中的常量(如字符串常量池里的字符串)
- 本地方法栈(JNI)中引用的对象
- 被 synchronized 持有的锁对象等
如果一个对象无法从任何 GC Root 出发到达,它就被判定为“不可达”,成为垃圾候选,后续可能被 GC 回收。
为什么置 null 不一定立刻回收
把引用变量设为 null 只是断开一条引用路径,并不等于对象立即消失:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 该对象可能还被其他变量、静态集合、缓存、监听器或线程栈持有
- 即使当前无可达路径,GC 也不会马上执行——它由 JVM 根据内存压力、回收策略和运行时状态决定触发时机
-
System.gc()仅是建议,JVM 可以忽略;现代 JVM 很少因这条调用真正执行 Full GC
类本身基本不被“销毁”
类的生命周期与其类加载器绑定:
- 启动类加载器、扩展类加载器、系统类加载器加载的类,在 JVM 运行期间几乎不会卸载
- 只有当自定义类加载器(如 Web 容器中的 ClassLoader)被回收,且它加载的所有类都不再被任何对象引用、也没有反射调用时,这些类才可能被卸载
- 类卸载是极少见场景,通常只发生在热部署、OSGi 或某些中间件容器中
所以日常开发中,“销毁类”不是你需要考虑的操作,重点应放在避免让对象意外保持可达——比如静态 Map 缓存未清理、线程未终止、监听器未反注册等。
常见导致对象无法回收的情况
以下写法会让本该回收的对象一直存活:
-
静态集合持有对象引用:如
private static Map<string user> cache = new HashMap();</string>,不手动 remove 就永不释放 - 内部类隐式持外部类引用:非静态内部类默认持有外部类 this,若内部类对象被长期持有(如传给线程池),外部类也跟着泄漏
-
ThreadLocal 未清理:线程复用场景下,ThreadLocal 变量若没调用
remove(),会随线程生命周期持续占用内存 - 未关闭资源或未注销回调:如数据库连接、文件流、GUI 事件监听器、RxJava 订阅等
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










