You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JDK1.8+元空间类信息布局规则及MetaspaceTest加载内存布局正误校验

JDK 1.8+ 环境下内存布局判断结果

你给出的7个理解大部分正确,其中第3、5、7点存在细节偏差,逐点说明如下:

public class MetaspaceTest {
    /* 
     1. "a"会被存入堆中的全局String Table;
     2. 执行[new String("a")]创建的对象会存放在堆中;
     3. 常量STR_OBJ会存放在MetaspaceTest类信息的常量池中,指向[new String("a")]创建的字符串对象;
    */
    private final static String STR_OBJ = new String("a");
    /* 
     4. "b"会被存入堆中的全局String Table;
     5. 静态字段literalStr会存放在metaspace中,指向已存入堆中全局String Table的字符串"b";
    */
    private static String literalStr = "b";
    /*
     6. 执行[new Integer(8)]创建的对象会存放在堆中;
     7. 静态字段intNum会存放在metaspace中,指向[new Integer(8)]创建的对象;
    */
    private static Integer intNum = new Integer(8);
}
  • 第1点:正确。JDK 8开始全局String Table从永久代移到了堆内存,类加载解析阶段字符串字面量"a"会被驻留到String Table中。
  • 第2点:正确。所有通过new关键字创建的对象实例都会分配在堆内存,这个新String对象和String Table中驻留的"a"是两个完全独立的对象。
  • 第3点:错误。这里有两个核心偏差:
    1. STR_OBJ是静态常量字段,存储位置是Metaspace中类元数据的静态字段区,不是类的运行时常量池;
    2. new String("a")是运行期执行的逻辑,编译期无法确定其引用,所以运行时常量池中只会存储字面量"a"的符号引用,不会存储这个new出来的对象的引用,引用只存在于静态字段STR_OBJ中。
  • 第4点:正确。逻辑和第1点一致,字面量"b"会在类加载阶段驻留到堆中的String Table。
  • 第5点:部分正确。静态字段literalStr确实存储在Metaspace的类静态字段区,但需要注意:String Table本身是引用哈希表,存储的是字符串实例的引用,实际的"b"字符串实例本身也在堆内存中,literalStr指向的是堆中的"b"实例,不是指向String Table本身。
  • 第6点:正确。通过new创建的Integer对象一定会在堆中分配,哪怕8属于Integer的默认缓存范围,主动new也会生成新的独立对象,不会复用缓存实例。
  • 第7点:部分正确。静态字段intNum的存储位置正确,确实指向你主动new出来的堆上的Integer对象,需要注意和Integer.valueOf(8)的场景做区分,后者才会返回缓存池中的对象引用。

内容的提问来源于stack exchange,提问作者Tom Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 20:06:00