类变量存于元空间(jdk 8+)或方法区(jdk 7及以前),属类所有、共享且生命周期与类一致;实例变量存于堆内存,属对象所有、独有且生命周期与对象绑定。

Java 实例变量和类变量在内存中的区分,核心看两点:**存储区域不同、生命周期绑定对象不同**。不是靠变量名或写法判断,而是由 JVM 在加载和运行时严格按规则分配。
类变量存在元空间(JDK 8+)或方法区(JDK 7 及以前)
类变量就是用 static 修饰的字段,它属于类本身,不依赖任何对象。JVM 在类加载阶段就为它分配内存:
- JDK 8 及以后:存放在 元空间(Metaspace),使用本地内存,不受堆大小限制
- JDK 7 及以前:存放在 永久代(PermGen),容易触发 OutOfMemoryError: PermGen space
- 整个类只有一份副本,所有实例共享,修改后立即对所有地方可见
- 生命周期从类加载开始,到类卸载结束;程序运行期间通常不会卸载,所以它基本“常驻”
实例变量分配在堆内存中
实例变量是未加 static 的非静态字段,它是对象状态的一部分,每次调用 new 创建对象时才分配:
- 连同对象头、实例数据一起,在 堆(Heap) 中开辟独立空间
- 每个对象都有自己的一份副本,地址不同、内容互不影响
- 生命周期绑定对象:对象创建时分配,GC 回收该对象时一并清理其所有实例变量
- 如果对象被静态集合、缓存等强引用持有,实例变量也会“陪绑”驻留,无法被回收
不能靠代码直接验证内存位置
你无法通过 System.identityHashCode()、== 或打印引用值来判断变量在哪块内存。这些操作反映的是对象标识或引用关系,不是内存段归属。
真正验证方式得用 JVM 工具:
- jmap -histo 查看堆中对象分布(能看到实例变量所属对象)
- jstat -gc 观察元空间使用情况(类变量相关)
- JVisualVM / JMC 结合内存快照分析类加载与对象实例分布
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











