String.intern()原理

String.intern()是一个Native方法,底层调用C++的 StringTable::intern 方法,源码注释:当调用 intern 方法时,如果常量池中已经该字符串,则返回池中的字符串;否则将此字符串添加到常量池中,并返回字符串的引用。

package com.ctrip.ttd.whywhy;
class Test {public static void main(String args[]) {String s1 = new StringBuilder().append("String").append("Test").toString();System.out.println(s1.intern() == s1);String s2 = new StringBuilder().append("ja").append("va").toString();System.out.println(s2.intern() == s2);}
}

在 JDK6 和 JDK7 中结果不一样:

1、JDK6的执行结果:false false
对于这个结果很好理解。在JDK6中,常量池在永久代分配内存,永久代和Java堆的内存是物理隔离的,执行intern方法时,如果常量池不存在该字符串,虚拟机会在常量池中复制该字符串,并返回引用,所以需要谨慎使用intern方法,避免常量池中字符串过多,导致性能变慢,甚至发生PermGen内存溢出。

2、JDK7的执行结果:true false
对于这个结果就有点懵了。在JDK7中,常量池已经在Java堆上分配内存,执行intern方法时,如果常量池已经存在该字符串,则直接返回字符串引用,否则复制该字符串对象的引用到常量池中并返回,所以在JDK7中,可以重新考虑使用intern方法,减少String对象所占的内存空间。

对于变量s1,常量池中没有 “StringTest” 字符串,s1.intern() 和 s1都是指向Java对象上的String对象。
对于变量s2,常量池中一开始就已经存在 “java” 字符串,所以 s2.intern() 返回常量池中 “java” 字符串的引用。

String.intern()性能

常量池底层使用StringTable数据结构保存字符串引用,实现和HashMap类似,根据字符串的hashcode定位到对应的数组,遍历链表查找字符串,当字符串比较多时,会降低查询效率。

在JDK6中,由于常量池在PermGen中,受到内存大小的限制,不建议使用该方法。
在JDK7、8中,可以通过-XX:StringTableSize参数StringTable大小,下面通过几个测试用例看看intern方法的性能

public class StringTest {
public class StringTest {public static void main(String[] args) {System.out.println(cost(1000000));}public static long cost(int num) {long start = System.currentTimeMillis();for (int i = 0; i < num; i++) {String.valueOf(i).intern();}return System.currentTimeMillis() - start;}
}

执行一百万次intern()方法,不同StringTableSize的耗时情况如下:
1、-XX:StringTableSize=1009, 平均耗时23000ms;
2、-XX:StringTableSize=10009, 平均耗时2200ms;
3、-XX:StringTableSize=100009, 平均耗时200ms;
4、默认情况下,平均耗时400ms;

在默认StringTableSize下,执行不同次intern()方法的耗时情况如下:
1、一万次,平均耗时5ms;
2、十万次,平均耗时25ms;
3、五十万次,平均耗时130ms;
4、一百万次,平均耗时400ms;
5、五百万次,平均耗时5000ms;
6、一千万次,平均耗时15000ms;
从这些测试数据可以看出,尽管在Java 7以上对intern()做了细致的优化,但其耗时仍然很显著,如果无限制的使用intern()方法,将导致系统性能下降,不过可以将有限值的字符串放入常量池,提高内存利用率,所以intern()方法是一把双刃剑。

转载于:https://blog.51cto.com/12666319/2114724

Java String的intern相关推荐

  1. Java String的intern方法

    1. 首先String不属于8种基本数据类型,String是一个对象. 因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. ne ...

  2. intern string java_聊聊java String的intern

    序 本文主要研究一下java String的intern String.intern() java.base/java/lang/String.java public final class Stri ...

  3. java String的intern()方法

    本文已参与「新人创作礼」活动,一起开启掘金创作之路. 本文章所用jdk版本为jdk1.8 先看第一个例子 public class HelloWorld {public static void mai ...

  4. java String.intern();

    0.引言 什么都先不说,先看下面这个引入的例子: [java] view plain copy String str1 = new String("SEU")+ new Strin ...

  5. Java中String类intern()详解

    1.背景 在开发过程中很多朋友,由于不会正确使用intern(),导致开发的程序,执行效率比较差.同时最近发现一道非常有意思的关于intern()的面试题,这道面试题还是有不小的难度,相信很多朋友看到 ...

  6. Java之String系列--intern方法的作用及原理

    原文网址:Java之String系列--intern方法的作用及原理_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Java的String的intern方法的原理. 常量池简介 在 JAVA 语言中 ...

  7. Java String intern()方法

    引言 在 JAVA 语言中有8中基本类型和一种比较特殊的类型String.这些类型为了使他们在运行过程中速度更快,更节省内存,都提供了一种常量池的概念.常量池就类似一个JAVA系统级别提供的缓存. 8 ...

  8. java string改变的影响_为什么Java的string类要设成immutable(不可变的)

    最流行的Java面试题之一就是:什么是不可变对象(immutable object),不可变对象有什么好处,在什么情况下应该用,或者更具体一些,Java的String类为什么要设成immutable类 ...

  9. 5.java String对象

    String 类 字符串广泛应用 在Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串. 实例化String类 实例化一个String类有两种方法: ...

最新文章

  1. 如何优雅的处理 Java 异常,可以参考这些建议
  2. NASA 顶级程序员是如何编程的?这里有十大准则
  3. 删除文件后,磁盘空间没有释放的处理记录
  4. 2020\Simulation_2\4.括号序列
  5. C++设计模式之装饰模式
  6. 信管专业c语言考什么,计算机信息管理专业卫生事业单位招聘考试笔试模拟题(十)...
  7. Caused by: javax.xml.stream.FactoryConfigurationError: Provider com.ctc.wstx.stax.WstxInputFactory n
  8. 垃圾收集器(CMS收集器 , G1收集器…)
  9. 移动测试基础 android 中 dumpsys 命令使用
  10. 移动端实现标题文字的截断
  11. Python学习 Day 039 - HTML
  12. 《梦断代码》阅读笔记03
  13. [golang 易犯错误] golang 局部变量初始化:=的陷阱
  14. 代码雨代码源复制_黑色帝国中代码雨如何实现?用python就可以了
  15. java扫描免费代理服务器
  16. SPSS入门教程—问卷的信度量化分析
  17. 5G 与 WIFI6 的对比
  18. 仿b站Java_推荐 9 个 GitHub 上练手项目(在线考试、仿美团、仿抖音、仿B站、仿头条...)...
  19. 专家,除了呼吁涨价你还会干点什么?
  20. 京东秋招java面试_最新秋招,京东技术中台Java开发面经,有想去面试的可以来看下...

热门文章

  1. c++ 顺序容器list的一个例子
  2. [BUUCTF-pwn]——bjdctf_2020_babyrop
  3. tacacs java客户端_思科交换机 ACS4.0 Tacacs+ 登陆验证
  4. c++ static allocator
  5. UML 中关系详解以及在visio中的表示
  6. Spring 3.0参考之SpEL
  7. SpringMVC以及SSM整合
  8. JavaEE课程目标、个人目标、互联网应用和企业级应用的区别
  9. Linux - chmod
  10. Android中获取手机电量信息