常量池

Java体系中,共有三种常量池。分别是字符串常量池、Class常量池和运行时常量池。

1、字符串池

       在JVM中,为了减少相同的字符串的重复创建,为了达到节省内存的目的。会单独开辟一块内存,用于保存字符串常量,这个内存区域被叫做字符串常量池。

       字符串常量池可以理解为运行时常量池分出来的部分。加载时,对于class的静态常量池,字符串都会被装到字符串常量池中。

     字符串驻留或池化机制:

              当字符串常量池中存在相同内容的字符串对象的引用,则返回这个引用;否则创建新的字符串对象,然后将这个引用放入字符串常量池,并返回该引用。

 

存储位置:

       JDK7之前的版本中,字符串常量池放在永久代中;

       JDK7将将其放到堆内存中;

       JDK8使用元空间代替永久代,即再次从堆内存移动到永久代中。

2、Class常量池

      Class常量池可以理解为Class文件中的资源仓库。Class文件中除了包含类的版本、字段、方法、接口等描述信息外,还有一项信息就是常量池,用于存放编辑器生成的各种字面量和符号引用。

      由于不同的Class文件中包含的常量的个数是不固定额,所以在Class文件中的常量池入口处会设置两个字节的常量池容量计数器,记录常量池中常量的个数。如下图:

java 常量池内存溢出 java的常量池_字符串常量池

     Class常量池的作用:Class是用来保存常量的一个媒介场所,并且是一个中间场所。在JVM真的运行时,需要把常量池中的常量加载到内存中。

3、运行时常量池

      运行时常量池是每一个类或接口的常量池的运行时表示形式。每一运行时常量池都分配在Java虚拟机的方法区中,在类和接口被加载到虚拟机后,对应的运行时常量池就被创建出来。

      除了这个方式之外,还有一种可以在运行期将字符串内容放置到字符串常量池的办法,那就是使用intern

intern功能

           在每次赋值的时候使用String的intern方法,如果常量池中有相同值,就会重复使用该对象,返回该对象引用。

 

补充:

String长度没有限制,但是Integer.MAX_VALUE,这个值大约等于4G 。所以在运行期,如果超过这个范围,就会抛出异常。

而在常量池中,常量池最大不能超多65535。这样即使string没有长度限制,也不能无限大。