Java整数字面量存储位置及PermGen空间相关技术疑问
Java字面量存储与PermGen空间详解
一、int x = 10;中字面量10的赋值逻辑
int x = 10;里的10不会先存储在PermGen再赋值给x。实际流程是:编译阶段,10会直接嵌入到字节码的bipush指令中(针对-128到127的int值),运行时JVM执行这条指令时,直接把10加载到当前栈帧的局部变量表,赋值给变量x,没有中间额外存储步骤。
二、int z = 2*x+y中字面量2的存储
和上述10的逻辑一致,字面量2也是编译时嵌入字节码指令,运行时直接加载到操作数栈参与计算,不会存储在PermGen空间里。
三、不同数据类型字面量的存储位置
1. 基本类型字面量(byte/short/int/long/float/double/char/boolean)
- 对于
int/short/byte/char类型中**-128到127范围的值,对应的包装类(如Integer)会在类加载时缓存到常量池(Java 7及之后常量池在堆内存,Java 6及之前在PermGen),但这是包装类对象的缓存**,不是基本类型字面量的存储。基本类型字面量本身编译时直接嵌入字节码,运行时直接加载到栈帧的局部变量表或操作数栈,不会单独存储到堆或PermGen。 - 超出上述范围的基本类型字面量,同样嵌入字节码,运行时直接加载,无额外存储环节。
- 浮点数(float/double)、长整型(long)字面量:编译时嵌入字节码,运行时直接加载,无类似整数的包装类缓存机制(少数特定场景除外,但基本类型本身不缓存)。
- 布尔型字面量
true/false:编译后对应字节码的iconst_1/iconst_0指令,直接加载,无单独存储。
2. 字符串字面量
- Java 6及之前:存储在PermGen的字符串常量池中。
- Java 7及之后:移至堆内存的字符串常量池,避免PermGen内存溢出问题。
3. null字面量
编译后对应字节码的aconst_null指令,运行时直接加载,无单独存储位置。
四、PermGen空间是什么?
PermGen(永久代)是Java 8及之前HotSpot虚拟机中的一块内存区域,属于方法区的具体实现,主要存储:
- 类的元数据(类结构、字段、方法定义、注解信息等)
- Java 6及之前的字符串常量池
- 静态变量
- JIT编译器编译后的代码缓存
Java 8及以后,PermGen被彻底移除,取而代之的是元空间(Metaspace),元空间直接使用本地内存(而非JVM堆内存),解决了PermGen固定大小导致的内存溢出问题。
你看到的“Java将字面量存储在PermGen”的说法,大概率是指Java 6时期的字符串常量池,基本类型字面量从来不会存储在PermGen中。
内容的提问来源于stack exchange,提问作者xyz
相关产品推荐
相关产品推荐

