Java优配_浅谈Java性能优化——String intern原理

intern方法解释

首先来看interna方法的说明:

/**

* Returns a canonical representation for the string object.

*

* A pool of strings, initially empty, is maintained privately by the

* class {@code String}.

*

* When the intern method is invoked, if the pool already contains a

* string equal to this {@code String} object as determined by

* the {@link #equals(Object)} method, then the string from the pool is

* returned. Otherwise, this {@code String} object is added to the

* pool and a reference to this {@code String} object is returned.

*

* It follows that for any two strings {@code s} and {@code t},

* {@code s.intern() == t.intern()} is {@code true}

* if and only if {@code s.equals(t)} is {@code true}.

*

* All literal strings and string-valued constant expressions are

* interned. String literals are defined in section 3.10.5 of the

* The Java™ Language Specification.

*

* @return a string that has the same contents as this string, but is

* guaranteed to be from a pool of unique strings.

*/

简单来说,在Java8中,String类维护了一个字符串常量池(注意此常量池在运行期间位于堆中),当调用intern方法时,首先在常量池中查看是否已有相同的字符串(字符串是否相同使用String的equal方法判断),如果常量池中已有,则直接返回该字符串的引用,如果没有,则将当前字符串对象加入常量池中,并返回当前字符串的引用。

字符串创建

字符串的创建,如果使用 new 创建时,是在堆中创建字符串对象,如果直接使用字面量,则先看常量池中是否有相等的字符串,如果有,则返回此字符串的引用,如果没有,则在常量池中创建。

举例

下面举例说明

String s1 = new String(String.valueOf(11));

String s2 = s1.intern();

这里使用String.valueOf(11)而不是“11”,是为了先说明非字符串常量的情况。

执行第一行代码时,内存中的数据如图1所示:

在堆中创建String "11" 对象,在栈中创建变量s1,指向String对象。

执行第二行代码时,调用String对象的intern方法,此时常量池中没有 "11",所以将"11"加入到常量池中,返回"11"对象的引用,赋值给s2, 内存中数据分布如图2所示:

16039757905e58d2dc7d20ae57ed577b.png

所以此时s1==s2,执行结果:

fe37dbb683762ee5108135e3039c1c23.png

下面看下字面量字符串和常量字符串的情况

String s1 = "11";

String s2 = new String("11");

String s3 = s2.intern();

System.out.println(s1 == s2);

System.out.println(s2 == s3);

System.out.println(s1 == s3);

对于字面量字符串和常量字符串是直接在string pool中创建, 所以s1指向常量池中的字符串对象;

s2使用new操作符,在堆中创建,所以s2指向堆中的字符串对象;

s2调用intern方法后,因为常量池中已经有“11”的字符串对象,所以直接返回常量池中的字符串引用。 内存中的数据分布如图3:

089438250bfb4710d21996c7c5d752bd.png

所以执行结果是:

97f2b5c159a993fd55557da560c568ec.png

优化配置

string pool是使用Map结构存储字符串及引用,如果想要增加string pool的大小,可以设置JVM参数:

-XX:StringTableSize=1000003

Java8中默认是60013,设置的值最好是素数,以减少Hash碰撞,提高查询效率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值