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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: JVM - 一个案例反推不同JDK版本的intern机制以及intern C++源码解析

20200712003202517.png

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 】

20200712170632176.png

【1.7 】


20200712170808392.png

【1.8】



20200712171037547.png


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


Jdk1.6及之前: JVM存在永久代, 运行时常量池在永久代,运行时常量池包含字符串常量池

Jdk1.7:有永久代,但已经逐步“去永久代”,字符串常量池从永久代里的运行时常量池分离到堆里

Jdk1.8及之后: 无永久代,变成了元空间,运行时常量池在元空间,字符串常量池里依然在堆里


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


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


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


JDK1.7(含)+

20200712224255430.png

JDK1.6


20200712224244643.png

明白了哈


intern源码

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

JDK8对应的哈


20200712235002244.png

20200712235124647.png


看看basic_add 返回的啥


20200712235213494.png


oop : ordinary object pointer 指针

2020071223530337.png


20200712235343990.png


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

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

相关文章
|
1月前
|
安全 编译器 程序员
【C++篇】C++类与对象深度解析(六):全面剖析拷贝省略、RVO、NRVO优化策略
【C++篇】C++类与对象深度解析(六):全面剖析拷贝省略、RVO、NRVO优化策略
47 2
|
21天前
|
自然语言处理 编译器 Linux
|
27天前
|
自然语言处理 编译器 Linux
告别头文件,编译效率提升 42%!C++ Modules 实战解析 | 干货推荐
本文中,阿里云智能集团开发工程师李泽政以 Alinux 为操作环境,讲解模块相比传统头文件有哪些优势,并通过若干个例子,学习如何组织一个 C++ 模块工程并使用模块封装第三方库或是改造现有的项目。
|
1月前
|
安全 C语言 C++
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
【C++篇】探寻C++ STL之美:从string类的基础到高级操作的全面解析
36 4
|
1月前
|
存储 安全 Java
JVM锁的膨胀过程与锁内存变化解析
在Java虚拟机(JVM)中,锁机制是确保多线程环境下数据一致性和线程安全的重要手段。随着线程对共享资源的竞争程度不同,JVM中的锁会经历从低级到高级的膨胀过程,以适应不同的并发场景。本文将深入探讨JVM锁的膨胀过程,以及锁在内存中的变化。
41 1
|
1月前
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
56 2
|
1月前
|
存储 设计模式 编译器
【C++篇】C++类与对象深度解析(五):友元机制、内部类与匿名对象的高级应用
【C++篇】C++类与对象深度解析(五):友元机制、内部类与匿名对象的高级应用
25 2
|
1月前
|
存储 安全 Java
jvm 锁的 膨胀过程?锁内存怎么变化的
【10月更文挑战第3天】在Java虚拟机(JVM)中,`synchronized`关键字用于实现同步,确保多个线程在访问共享资源时的一致性和线程安全。JVM对`synchronized`进行了优化,以适应不同的竞争场景,这种优化主要体现在锁的膨胀过程,即从偏向锁到轻量级锁,再到重量级锁的转变。下面我们将详细介绍这一过程以及锁在内存中的变化。
37 4
|
12天前
|
Arthas 监控 Java
JVM进阶调优系列(9)大厂面试官:内存溢出几种?能否现场演示一下?| 面试就那点事
本文介绍了JVM内存溢出(OOM)的四种类型:堆内存、栈内存、元数据区和直接内存溢出。每种类型通过示例代码演示了如何触发OOM,并分析了其原因。文章还提供了如何使用JVM命令工具(如jmap、jhat、GCeasy、Arthas等)分析和定位内存溢出问题的方法。最后,强调了合理设置JVM参数和及时回收内存的重要性。
|
10天前
|
Java Linux Windows
JVM内存
首先JVM内存限制于实际的最大物理内存,假设物理内存无限大的话,JVM内存的最大值跟操作系统有很大的关系。简单的说就32位处理器虽然可控内存空间有4GB,但是具体的操作系统会给一个限制,这个限制一般是2GB-3GB(一般来说Windows系统下为1.5G-2G,Linux系统下为2G-3G),而64bit以上的处理器就不会有限制。
10 1