Java八大原始类型值直接存于栈帧局部变量表:int/float/char/short/byte/boolean占1个32位slot,long/double占2个连续slot;生命周期与栈帧绑定,方法结束即释放,不触发GC。

Java 虚拟机对 8 种原始类型(byte、short、int、long、float、double、char、boolean)采用统一的内存布局原则:它们的值直接存储在栈(Stack)内存中,不涉及堆(Heap)分配,也不产生对象头或引用开销。
原始类型全部存于栈帧局部变量表
方法执行时,JVM 为每个方法调用创建一个栈帧(Stack Frame),其中包含局部变量表(Local Variable Table)。所有原始类型变量——无论声明在方法参数、局部变量还是 for 循环控制变量中——都以固定槽位(slot)形式直接存入该表:
- 每个 slot 占 32 位(1 个 word),int/float/char/short/byte/boolean 占 1 个 slot;
- long/double 占 2 个连续 slot(因需 64 位对齐);
- 变量名只是符号引用,真正运行时靠 slot 索引快速定位,无需查表或解引用。
值存储即数据本身,无间接寻址
原始类型变量不保存地址,而是把数值原样写入对应 slot:
-
int x = 100;→ 栈中 slot 存放二进制补码0x00000064; -
char c = 'A';→ 存放 Unicode 码点0x0041(2 字节,高位补零占满 slot); -
boolean b = true;→ JVM 规范未强制字节数,主流实现(HotSpot)用 1 字节或 4 字节填充,但语义上只取0或非0判定。
生命周期与栈帧强绑定
原始类型变量的生命期完全由所在方法的执行周期决定:
立即学习“Java免费学习笔记(深入)”;
- 方法进入时,栈帧分配完成,所有原始变量 slot 初始化为默认值(如
0、false、\u0000); - 方法返回时,整个栈帧弹出,所有原始值随栈空间自动释放,不触发 GC;
- 不存在“逃逸”问题——原始类型无法被其他线程或方法长期持有,因为它们没有地址可传递。
与包装类的关键区别就在这里
对比 Integer i = 100; 这类写法:
- 变量
i是引用类型,它本身(4 或 8 字节地址)存在栈中; - 实际
Integer对象(含对象头、字段、对齐填充)一定分配在堆中; - 即使触发缓存(如 -128~127 的 Integer),也只是复用已有堆对象,引用变量仍存栈。
不复杂但容易忽略:原始类型不是“轻量级对象”,它们根本就不是对象——没有类、没有方法、没有身份哈希码,只有纯数据和确定的内存位置。


















