QT数据结构内存分配策略
在QT的Reference中无意看到了QString及其他类型数据结构内存的分配策略,翻译并记录一下。
在QString的数据结构中,QString通过一次附加一个字符来动态构建字符串。假设我们向QString字符串追加15000个字符。然后,当QString空间不足时,会发生以下18个重新分配的过程(假设目前有15000个字符):
4,8,12,16,20,52,116,244,500,1012,2036,4084,6132,8180,10228, 12276、14324、16372
最后,QString分配了16372个Unicode字符,其中15000个被占用。
上面的内存分配状况看起来比较奇怪,以下是内存分配原则:
1、QString一次分配4个字符,直到达到大小20。
2、从20到4084,每次将大小增加一倍。更准确地说,它的内存分配量扩大到2的下一个乘方数减去12。(某些内存分配器在要求精确的2的乘方数时表现最差,因为它们每个块还需要使用额外的几个字节进行记录。)
3、从4084开始,每次分配2048个字符(4096字节)的内存块。因为现代操作系统在重新分配缓冲区时不会复制整个数据。只需简单地对物理内存页面进行重新排序,并且实际上只需要复制首页和最后一页上的数据。
QByteArray和QList
QVector
QHash
对于大多数应用程序,Qt提供的默认增长算法可以解决问题。如果需要更多控制,QVector
1、Capacity()返回为其分配内存的项目数(对于QHash和QSet,为哈希表中的存储桶数)。
2、reserve(size)显式预分配大小项目的内存。
3、squeeze()释放不需要存储项目的任何内存。
如果在一开始就知道一个容器中存储大约多少个项目,则可以通过调用reserve()将内存分配完成,减少过程中不必要的内存分配,并在完成容器的填充后,可以调用squeeze()释放额外的预分配内存。