静态变量的生命周期与类相同,从类加载时初始化,存储于方法区(元空间),随类卸载而销毁;其存在依赖class对象是否被jvm强引用,通常持续至jvm退出。

静态变量的生命周期完全绑定于类对象(Class 对象)的生命周期,而非堆中的任何实例。它不随对象创建而诞生,也不随对象销毁而消失;它的存在与否,只取决于 JVM 是否还持有该类对应的 Class 对象引用。
静态变量在类加载时初始化,存储于方法区
当 JVM 第一次主动使用某个类(如调用静态方法、访问静态字段、new 实例、反射获取 Class 等),触发类加载过程:加载 → 链接(验证、准备、解析)→ 初始化。在“准备”阶段,静态变量被分配内存并设默认值;在“初始化”阶段,执行 static {} 块和静态字段显式赋值语句。
此时,静态变量实际存储在方法区(JDK 8+ 为元空间),不是堆内存。它属于类本身,所有实例共享同一份数据。
静态变量的存活依赖 Class 对象是否可达
静态变量不会单独被 GC,但它的“存在状态”由其所属的 Class 对象决定。只要该 Class 对象仍被强引用,静态变量就一直有效。而 Class 对象能否被卸载,需同时满足三个条件:
- 该类所有实例均已从堆中被 GC 回收
- 加载该类的
ClassLoader实例本身已被 GC 回收 - 该类的
Class对象没有任何强引用(包括MyClass.class、静态字段持有了该 Class 的引用、反射调用痕迹等)
三者缺一不可。只要任意一条不满足,类就不会卸载,静态变量也就持续存在。
常见导致静态变量长期驻留的场景
以下情况会让 Class 对象无法被回收,从而让静态变量“意外长存”:
- 静态变量直接持有本类或子类的实例引用(形成“Class ←→ 实例”的双向强引用链)
- 自定义
ClassLoader未被释放,且它加载的类仍有静态引用 - 通过
ThreadLocal、监听器、回调接口等间接持有静态变量所关联对象的引用 - Android 中 Application 或 Activity 的静态引用未清理,尤其在配置变更或进程后台驻留时
回收时机:仅发生在类卸载时,通常等于 JVM 退出
在绝大多数标准 Java 应用(含 Spring 单例容器)中,系统类加载器(Bootstrap/Extension/AppClassLoader)生命周期与 JVM 一致,不会被回收。因此,由它们加载的类几乎永不卸载,静态变量也始终存在。
只有在动态类加载场景(如 OSGi、热部署容器、自定义 ClassLoader 配合弱引用管理)中,才可能触发类卸载——此时静态变量占用的方法区内存才会被真正释放。
简单说:静态变量不归 GC 管,它归类加载器和 Class 对象管;它什么时候消失,取决于类什么时候真正“退场”。










