JAVA中字符串常量池和缓冲池理解与作用[通俗易懂]

JAVA中字符串常量池和缓冲池理解与作用[通俗易懂]字符串池与常量池是完全不同的两个东西,但是很多地方都喜欢把它们混为一谈,很容易让初学者产生误解,在这里我想好好讨论一下它们。字符串池也可以被称为字符串常量池,我认为这个名称就是产生误解的根源,有些人说着说着就把字符串三个字省略了,只剩下了常量池…所以为了避免误解,我建议在指代字符串对象的缓存池的时候,就直接称之为字符串池1常量池常量池分为两个类型,一是.class文件中静态的常量池,二是.class文件中的静态常量池被加载到JVM中而形成的运行时常量池。1.1静态常量池.cla

大家好,欢迎来到IT知识分享网。

字符串池与常量池是完全不同的两个东西,但是很多地方都喜欢把它们混为一谈,很容易让初学者产生误解,在这里我想好好讨论一下它们。

字符串池也可以被称为字符串常量池,我认为这个名称就是产生误解的根源,有些人说着说着就把字符串三个字省略了,只剩下了常量池… 所以为了避免误解,我建议在指代字符串对象的缓存池的时候,就直接称之为字符串池

1 常量池

常量池分为两个类型,一是.class文件中静态的常量池,二是.class文件中的静态常量池被加载到JVM中而形成的运行时常量池

1.1 静态常量池

.class文件中的常量池可以看作一个数组,数组中存储了一些常量,当需要在字节码指令中用到这个常量的时候,就通过数组的索引来访问它。

看下面的代码:

 String m = "hellohellohellohellohello";
 String n = "hellohellohellohellohello";

IT知识分享网

它在字节码中将会是这种形式:

IT知识分享网 // 常量池:
 #1 hellohellohellohellohello
 #2 ...
 ...
 ----------------------------
 ​
 String m = #1;
 String n = #1;

当然,这只是一个简化的版本,实际上要更加复杂 (实际的版本可以看文章末尾参考资料部分里面贴出的那个回答,目前可以先只考虑简化的版本)

注意,在这个里面存储的字符串常量只是一个简单的UTF8编码的字节序列,而不是Java的字符串对象,它就和你在一个txt文本中存储的字符串一样,我们用UTF8格式来打开一个.class文件,可以看到hellohellohellohellohello是可以被解析的:JAVA中字符串常量池和缓冲池理解与作用[通俗易懂]

1.2 运行时常量池

理解了静态的常量池之后,运行时常量池就很容易想明白了。简单来说,运行时常量池就是.class文件中的静态常量池在JVM中的运行时表示,每一个.class文件的静态常量池都会生成一个对应的运行时常量池。等到JVM在解释String m = #1这条指令时,它可以去这个类的运行时常量池中查找#1的定义。

2 字符串池

字符串池是Java为了重用String对象而设置的一个缓存池,Java1.7之前设置在方法区上,保存的是String对象;Java1.7之后设置在堆上,保存的是String对象的引用,String对象本身存在于堆上的其他位置。下文中以Java1.7之后的情况为标准。

继续上面的例子。当JVM在解释String m = #1时,它已经从运行时常量池拿到了相应的UTF8序列,接下来,它会在字符串池中寻找和这个UTF8序列对应的String对象,并把这个对象的引用赋值给m。你可能会好奇这个String被创建的时机,根据R大的这篇文章,在这条语句所在的类被加载时,如果字符串池中已经存在对应的对象了,那么就什么都不做,如果不存在,就会创建一个对应的String对象,并把其引用放入池中。

除了字符串池,IntegerLong等Wrapper类型也有自己的缓存池,比如Integer会缓存从-128~127的Integer对象,当使用字面量赋值或者Integer.valueOf()时,如果池中存在相应的对象,就会返回池中的对象,只有当池中没有时才会在堆上创建新对象。

不过,和字符串池不同的时,这些Wrapper池不会像字符串池一样可以增长,也就是池中的对象数目是固定的,Integer池中只会有-128~127。

基本类型对应的缓冲池如下:

boolean values true and false
all byte values
short values between -128 and 127
int values between -128 and 127
char in the range \u0000 to \u007F

在 jdk 1.8 所有的数值类缓冲池中,Integer 的缓冲池 IntegerCache 很特殊,这个缓冲池的下界是 – 128,上界默认是 127,但是这个上界是可调的,在启动 jvm 的时候,通过 -XX:AutoBoxCacheMax= 来指定这个缓冲池的大小,该选项在 JVM 初始化的时候会设定一个名为 java.lang.IntegerCache.high 系统属性,然后 IntegerCache 初始化的时候就会读取该系统属性来决定上界。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/7620.html

(0)
上一篇 2023-01-05 17:42
下一篇 2023-01-05 17:42

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信