JVM - 一个案例反推不同JDK版本的intern机制以及intern C++源码解析


在这里插入图片描述

Pre

JVM - 深入剖析字符串常量池


案例

      String str2 = new StringBuilder("计算机").append("技术").toString();
      System.out.println(str2 == str2.intern()); 

      String s2 = new StringBuilder("计算机技术").toString();
      System.out.println(s2 == s2.intern());  

读者可以先自行推演一下答案 ,是不是所有的JDK版本都是一样的? 还是说不同的JDK版本的答案不尽相同 ?


答案

        String str2 = new StringBuilder("计算机").append("技术").toString();
        System.out.println(str2 == str2.intern());  //1.8 true  1.6 false

        String s2 = new StringBuilder("计算机技术").toString();
        System.out.println(s2 == s2.intern());  //1.8 false    1.6 false 

【1.6 】
在这里插入图片描述

【1.7 】

在这里插入图片描述

【1.8】

在这里插入图片描述


字符串常量池在不同JDK版本的位置变化

  • Jdk1.6及之前: JVM存在永久代, 运行时常量池在永久代,运行时常量池包含字符串常量池
  • Jdk1.7:有永久代,但已经逐步“去永久代”,字符串常量池从永久代里的运行时常量池分离到堆里
  • Jdk1.8及之后: 无永久代,变成了元空间,运行时常量池在元空间,字符串常量池里依然在堆里

String中的intern方法是一个 native 的方法

  • JDK1.7(含) + ,当调用 intern方法时,如果池已经包含一个等于此String对象的字符串(用equals(oject)方法确定),则返回池中的字符串, 否则,将intern返回的引用指向当前字符串

  • jdk1.6版本需要将 s1 复制到字符串常量池里


JDK1.7(含)+

在这里插入图片描述

JDK1.6

在这里插入图片描述

明白了哈


intern源码

intern 在JDK里是native ,所以只能找C++的代码了。

JDK8对应的哈

在这里插入图片描述

在这里插入图片描述

看看basic_add 返回的啥

在这里插入图片描述

oop : ordinary object pointer 指针
在这里插入图片描述

在这里插入图片描述

加入到常量池,这个常量池StringTable , 也是个hash结构 ,最后返回string(), 这其实是个指针引用。

so ~ , 这样就好理解intern机制了吧 。

猜你喜欢

转载自blog.csdn.net/yangshangwei/article/details/107293878
今日推荐