美文网首页
StringBuilder类源码剖析_内存分配算法:指数扩容

StringBuilder类源码剖析_内存分配算法:指数扩容

作者: entro | 来源:发表于2019-04-02 22:28 被阅读0次

String

jdk9对String的实现进行了优化,内部不再是char数组,而是byte数组。
当字符都是Ascii字符的时候,将使用一个字节表示一个字符,而不是UTF-16BE编码。

String内部的char数组是final类型的,每次拼接要重新分配内存。
为了高效,在较多的拼接需求的时候,要使用StringBuilder和StringBuffer类来拼接字符串。

两者的实现几乎一样,只是StringBuffer是线程安全的,这里来看下StringBuilder的源码。
StringBuilder源码的核心是扩容算法。

StringBuilder 扩容机制

StringBuilder 继承抽象类AbstractStringBuilder。
其默认构造,调用父类构造函数并传入16。

public StringBuilder() {
   super(16);
}

即默认生成一个长度为16的char数组

AbstractStringBuilder(int capacity) {
    value = new char[capacity];
}

当拼接字符串,调用append时会通过调用ensureCapacityInternal()方法检查char数组长度是否够用,不够则调用expandCapacity()方法来扩容。
expandCapacity()方法是StringBuilder扩容的核心函数。
使用指数+2扩容算法。

    void expandCapacity(int minimumCapacity) {
        int newCapacity = value.length * 2 + 2;
        if (newCapacity - minimumCapacity < 0)
            newCapacity = minimumCapacity;
        if (newCapacity < 0) {
            if (minimumCapacity < 0) // overflow
                throw new OutOfMemoryError();
            newCapacity = Integer.MAX_VALUE;
        }
        value = Arrays.copyOf(value, newCapacity);
    }

为什么要使用指数扩容算法?为什么要+2?

第一个问题:指数扩容是一种折中的算法,因为一方面要减少内存分配次数,另一方面要避免浪费内存。
不知道最终需要多长的情况下,指数扩容是一种常见的策略,广泛应用于各种内存分配相关的计算机程序中。

第二个问题:为什么要+2?因为StringBuilder提供了一个构造函数,可以指定初始数组的大小public StringBuilder(int capacity).
如果capacity = 0的情况下就不能正常扩容了。所以+2。

相关文章

网友评论

      本文标题:StringBuilder类源码剖析_内存分配算法:指数扩容

      本文链接:https://www.haomeiwen.com/subject/djfobqtx.html