结合官方《JAVA虚拟机规范》来验证JVM中运行时常量池的存放位置

3 篇文章 0 订阅

先说结论

1.6-1.8所有的运行时常量池都在方法区中!!!

注意这里说的是 运行时常量池
JVM大概有三种容易搞混的常量池
1、常量池(也有人叫class常量池)
2、运行时常量池
3、字符串常量池

看官方文档来证明结论

JAVA SE1.6 虚拟机规范

连接地址:
JAVA SE1.6 虚拟机规范,第3.5.5章节,描述运行时常量池
官方部分原文:

3.5.5 Runtime Constant Pool
A runtime constant pool is a per-class or per-interface runtime representation of the constant_pool table in a class file (§4.4). It contains several kinds of constants, ranging from numeric literals known at compile time to method and field references that must be resolved at run time. The runtime constant pool serves a function similar to that of a symbol table for a conventional programming language, although it contains a wider range of data than a typical symbol table.
Each runtime constant pool is allocated from the Java virtual machine’s method area (§3.5.4). The runtime constant pool for a class or interface is constructed when the class or interface is created (§5.3) by the Java virtual machine.

译文: “每个运行时常量池都是从Java虚拟机的方法区域分配的”

JAVA SE1.7 虚拟机规范

连接地址:
JAVA SE1.7 虚拟机规范,第2.5.5章节,描述运行时常量池
官方部分原文:

2.5.5. Run-Time Constant Pool
A run-time constant pool is a per-class or per-interface run-time representation of the constant_pool table in a class file (§4.4). It contains several kinds of constants, ranging from numeric literals known at compile-time to method and field references that must be resolved at run-time. The run-time constant pool serves a function similar to that of a symbol table for a conventional programming language, although it contains a wider range of data than a typical symbol table.
Each run-time constant pool is allocated from the Java Virtual Machine’s method area (§2.5.4). The run-time constant pool for a class or interface is constructed when the class or interface is created (§5.3) by the Java Virtual Machine.

译文: “每个运行时常量池都是从Java虚拟机的方法区域分配的”

JAVA SE1.8 虚拟机规范

连接地址:
JAVA SE1.8 虚拟机规范,第2.5.5章节,描述运行时常量池
官方部分原文:

2.5.5. Run-Time Constant Pool
A run-time constant pool is a per-class or per-interface run-time representation of the constant_pool table in a class file (§4.4). It contains several kinds of constants, ranging from numeric literals known at compile-time to method and field references that must be resolved at run-time. The run-time constant pool serves a function similar to that of a symbol table for a conventional programming language, although it contains a wider range of data than a typical symbol table.
Each run-time constant pool is allocated from the Java Virtual Machine’s method area (§2.5.4). The run-time constant pool for a class or interface is constructed when the class or interface is created (§5.3) by the Java Virtual Machine.

译文: “每个运行时常量池都是从Java虚拟机的方法区域分配的”

JVM中的各种常量池

1、常量池

常量池,就是是在一个class文件中的,编译出来保存在class文件中,可以通过 javap -v 命令区解析一个class文件后, Constant pool 就是,主要存储了类的一些信息。
JVM 启动时,会根据class文件信息去加载一个类,常量池则是在加载后放到方法区的运行时常量池

public class Demo {
    private static final String s ="a";
    private static final String s1 ="b";
}

经过 javap -v Demo.class 查询class文件中包含的详细信息
在这里插入图片描述
当然,在运行阶段"a" 和 “b” 一定是放在堆中的字符串常量池中。

2、运行时常量池

会把class文件的信息加载后,存放到运行时常量池中,并且还会把常量池中的符合引用翻译出来的直接引用也存到运行时常量池中。
与常量池不同的是,常量池在经过编译后常量池就已经确定了,而运行时运行时常量池可以在运行期间可以放入新的常量,比如String类的intern()方法
注意
intern()方法
在1.6是将首次遇到的字符串拷贝到永久带的常量池中。
在1.7后(包含1.7),因为字符串常量池被移到堆中了,所以在运行时常量池中只用记录一下引用

3、字符串常量池

字符串常量池在不同的JDK版本中位置不一样
1.6:字符串常量池在永久带
1.7:准备移除永久带,先移除一部分,字符串常量池、静态变量从永久带移除,转到堆内存中
1.8:永久带被完全移除,被元空间取代,字符串常量池、静态变量依然在堆中

证明

public class Demo {
  public static  String s ="a";
  public static void main(String[] args) throws IOException {
        for (int i = 0; i < 1000; i++) {
            String s1 = s+s;
            s = s1.intern();
        }
  }
}

在1.6环境下运行,抛出永久代OOM

Exception in thread "main" java.lang.OutOfMemoryError: PermGen space  

在1.7、1.8环境下运行,抛出堆区OOM

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space  

JVM内存模型图

下面的图是我自己画的,有任何问题都可以提出来
在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值