静态变量存放在元空间(jdk 8+的方法区实现),基本类型值直接存储,引用类型仅存堆中对象地址;随类加载而初始化,线程共享且不属堆内存,过多类加载易引发metaspace oom。

静态变量存放在方法区,准确说是元空间(Metaspace)——这是 JDK 8 及以后版本中方法区的具体实现。
方法区是线程共享区域,不归堆内存管理。静态变量(即类变量)随类加载而进入方法区,和类的结构信息(如字段、方法、常量池等)一起存放。它不随对象创建而分配,也不在堆里;哪怕没创建任何实例,只要类被加载,静态变量就已存在。
静态变量在方法区里的存储方式分两类:
- 基本类型(如
static int x = 10;):值直接存于方法区 - 引用类型(如
static Person p = new Person();):- 变量本身(即引用
p)存在方法区 -
new Person()创建的实际对象仍存在堆中 - 方法区只存这个对象在堆中的地址
- 变量本身(即引用
初始化顺序影响实际存放时机:
- 类加载时先做默认初始化(如
int→0,Object→null) - 再执行显式赋值(
static int a = 5;)和静态代码块 - 这些过程都发生在方法区,且只执行一次
注意几个常见误区:
- 静态变量 ≠ 存在堆中(哪怕它指向堆对象)
- 方法区不是“存方法的地方”,而是存类元数据+静态变量+运行时常量池
- 元空间用的是本地内存(native memory),大小受限于物理内存,不像永久代那样受 JVM 堆参数约束
如果大量动态生成类(比如某些 ORM、热部署、字节码增强场景),静态变量连带类定义会持续占用元空间,可能触发 OutOfMemoryError: Metaspace。可通过 -XX:MaxMetaspaceSize 限制上限,但更根本的是检查类加载器泄漏或不必要的类重复加载。











