• JVM-String Tab字符串常量池


    String Tab

    1、String基本特性

    • final修饰、不可继承

    • 实现Serializable:可序列化

    • 实现Comparable:可排序比较大小

    • jdk8及以前使用final char value[]存储,之后改为byte[]

      • 原因:char占两个字节,byte占一个字节,大部分情况下使用的都是拉丁字符(占一个字节)、避免浪费
    • 字符串常量池中不会存储相同内容的字符串

      • String Pool是一个固定大小的HashTable,String过多容易hash冲突、链表过长 、tring.intern性能下降

      • 设置长度:-XX:StringTableSize

      • String Table默认大小1009(jdk6,设置大小无要求),60013(jdk7)、jdk8开始1009是可设置的最小值

        image-20200807231134442

        c如果设置最小值小于1009、报错

        image-20200807231312478

    2、String内存分配

    • Java 6及以前,字符串常量池存放在永久代

    • Java 7 中 Oracle 的工程师对字符串池的逻辑做了很大的改变,即将字符串常量池的位置调整到Java堆内
      所有的字符串都保存在堆(Heap)中,和其他普通对象一样,这样可以让你在进行调优应用时仅需要调整堆大小就可以了。字符串常量池概念原本使用得比较多,但是这个改动使得我们有足够的理由让我们重新考虑在Java7中使用string.intern()。

    • Java8元空间,字符串常量在堆

      为什么调整位置?

    3、字符串拼接操作

    1.常量与常量(常量引用,如final修饰的常量)的拼接结果在常量池,原理是编译期优化

    image-20200810194909184

    image-20200810200831688

    2.常量池中不会存在相同内容的常量。

    3.只要其中有一个是变量,结果就在堆中。变量拼接的原理是stringBuilder

    image-20200810195148935

    image-20200810200455659

    StringBuilder拼接字符串与 ‘+’ 拼接字符串差别

    • StringBuild的append方式:
      • 自始至终只创建一个StringBuilder对象
      • 优化:可以根据实际情况,给出一个限定值作为参数来创建构造器,避免多次扩容
    • ‘+’拼接的方式:
      • 调用了多少次拼接就创建了多少个StringBulider和String对象、导致内存占用过多,GC需要更多时间

    4.如果拼接的结果调用intern()方法,则主动将常量池中还没有的字符串对象放入池中,并返回此对象地址。

    4、intern()使用

    返回的是字符串在常量池中的地址(如果没有该字符串将会加载一个、再返回)

    native方法

    Interned string就是确保字符串在内存里只有一份拷贝,这样可以节约内存空间,加快字符串操作任务的执行速度。注意,这个值会被存放在字符串内部池(String Intern Pool)。

    • jdk1.6中,将这个字符串对象尝试放入串池。
      • 如果串池中有,则并不会放入。返回已有的串池中的对象的地址
      • 如果没有,会把此对象复制一份,放入串池,并返回串池中的对象地址
    • Jdk1.7起,将这个字符串对象尝试放入串池。
      • 如果串池中有,则并不会放入。返回已有的串池中的对象的地址
      • 如果没有,则会把对象的引用地址复制一份,放入串池,并返回串池中的引用地址

    对于程序中存在大量重复字符串、使用intern方法能够接合适呢个内存空间

    面试题

    new String(“ab”)会创建几个对象?

    答案:两个。一个是通过new关键字在堆空间创建的;另一个是字符串在常量池中的对象

    拓展:new String(“a”)+new String (“b”)呢?

    答案:6个。

    new StringBuilder()

    new String(“a”)

    “a”

    new String(“b”)

    ”b”

    new String(“ab”)

    注意:常量池中并不存在“ab”

    image-20200811200908129

    拓展:

    image-20200811201854853

    拓展:

    image-20200811202025900

    拓展:

    image-20200811202457295

    String tab的垃圾回收

  • 相关阅读:
    消息队列(一)
    Servlet3.1学习(三)
    再弄一片文章凑个4篇文章的数,主要是用于XML和 Binary序列化和反序列化的类
    Entity Framework底层操作封装(3)
    Entity Framework底层操作封装(2)
    Entity Framework底层操作封装(1)
    实现合并区间
    socket简单案例实现
    PostgreSQL11.2数据恢复记录(From Physical Files)
    Spring Data JPA 与 MyBatis 对比分析
  • 原文地址:https://www.cnblogs.com/jklixin/p/13607315.html
Copyright © 2020-2023  润新知