• 【JVM--StringTable字符串常量池】


    1. String 的基本特性

    • String 声明为 final 的,不可被继承
    • String 实现了 Serializable 接口:表示字符串是支持序列化的。
    • String 实现了 Comparable 接口:表示 string 可以比较大小
    • String 在 jdk8 及以前内部定义了 final char[] value 用于存储字符串数据。JDK9 时改为 byte[]

    String 的 String Pool 是一个固定大小的 Hashtable

    2. 字符串拼接操作

    • 常量常量的拼接结果在常量池,原理是编译期优化
    • 只要其中有一个是变量,结果就在中。变量拼接的原理是== StringBuilder==
    • 如果拼接的结果调用 intern()方法,则主动将常量池中还没有的字符串对象放入池中,并返回此对象地址(将堆中字符串的地址写到字符串常量池这个位置,字符串常量池中存的是堆中对象的引用)

    常量与常量拼接,编译期优化:

    在这里插入图片描述

    只要有一个变量,就是在堆中,用string builder拼接,最后返回.tostring变为字符串

    在这里插入图片描述

    不使用 final 修饰,即为变量。如 s3 行的 s1 和 s2,会通过 new StringBuilder 进行拼接
    使用 final 修饰,即为常量。会在编译器进行代码优化。在实际开发中,能够使用 final 的,尽量使用

    在这里插入图片描述

    3. intern()的使用

    DK1.7 起,将这个字符串对象尝试放入串池。

    • 如果串池中有,则并不会放入。返回已有的串池中的对象的地址
    • 如果没有,则会把对象的引用地址(就是将堆中这个对象的地址)复制一份,放入串池,并返回串池中的引用地址

    4. StringTable 的垃圾回收

    许多大规模的 Java 应用的瓶颈在于内存,测试表明,在这些类型的应用里面,Java 堆中存活的数据集合差不多 25%是 String 对象。更进一步,这里面差不多一半 string 对象是重复的,重复的意思是说: stringl.equals(string2)= true堆上存在重复的 String 对象必然是一种内存的浪费。这个项目将在 G1 垃圾收集器中实现自动持续对重复的 string 对象进行去重,这样就能避免浪费内存。

    实现

    1. 当垃圾收集器工作的时候,会访问堆上存活的对象。对每一个访问的对象都会检查是否是候选的要去重的 String 对象
    2. 如果是,把这个对象的一个引用插入到队列中等待后续的处理。一个去重的线程在后台运行,处理这个队列。处理队列的一个元素意味着从队列删除这个元素,然后尝试去重它引用的 string 对象。
    3. 使用一个 hashtable 来记录所有的被 String 对象使用的不重复的 char 数组。当去重的时候,会查这个 hashtable,来看堆上是否已经存在一个一模一样的 char 数组。
    4. 如果存在,String 对象会被调整引用那个数组,释放对原来的数组的引用,最终会被垃圾收集器回收掉。
    5. 如果查找失败,char 数组会被插入到 hashtable,这样以后的时候就可以共享这个数组了。
  • 相关阅读:
    分享PPT设计思路,让你的PPT更吸睛
    2024.4.24
    Elasticsearch搜索功能的实现(五)-- 实战
    STM32简易音乐播放器(HAL库)
    如何制作网页-初学者入门HTML+CSS
    音频怎么转文字?学会这3招,轻松拉满你的工作效率
    浅谈UI自动化测试
    linux中使用ps查看进程的所有线程
    React报错之useNavigate() may be used only in context of Router
    Python150题day07
  • 原文地址:https://blog.csdn.net/qq_51240148/article/details/133707463