在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 <T>使用与QString大致相同的算法。

  QVector <T>还将该算法用于可以使用memcpy()在内存中移动的数据类型(包括基本的C++类型,指针类型和Qt的共享类),但对只能用于通过调用复制构造函数和析构函数进行移动。由于在这种情况下重新分配的成本较高,因此QVector <T>在空间不足时,始终通过将内存翻倍来减少重新分配的次数。

  QHash <Key,T>是完全不同的情况。 QHash的内部哈希表以2的幂次方增长,并且每次增长时,这些项都将重新放置在新的存储桶中,计算方式为qHash(key)%QHash::capacity()(存储桶数)。此注释也适用于QSet <T>和QCache <Key,T>。

  对于大多数应用程序,Qt提供的默认增长算法可以解决问题。如果需要更多控制,QVector <T>,QHash <Key,T>,QSet <T>,QString和QByteArray提供了三个函数,可让您检查并指定用于存储项目的内存量:

  1、Capacity()返回为其分配内存的项目数(对于QHash和QSet,为哈希表中的存储桶数)。
  2、reserve(size)显式预分配大小项目的内存。
  3、squeeze()释放不需要存储项目的任何内存。
  如果在一开始就知道一个容器中存储大约多少个项目,则可以通过调用reserve()将内存分配完成,减少过程中不必要的内存分配,并在完成容器的填充后,可以调用squeeze()释放额外的预分配内存。

最新文章

  1. PHP 之 CURL 模拟登陆并获取数据
  2. 谢欣伦 - OpenDev原创教程 - 媒体开发库libMedia
  3. PHP使用XHProf进行性能分析
  4. centos7安装mplayer 错误集锦
  5. LeetCode——Jump Game
  6. 高阶函数复习:利用reduce和map把字符串转为数字
  7. C++定义构造函数必须使用初始化列表的场合
  8. VS-FluentData 单元测试
  9. ASP.NET环境下集成CKEditor与CKEditor实现文件上传
  10. hibernate与mybatis的区别
  11. webpack学习笔记(二)-- 初学者常见问题及解决方法
  12. Unity 游戏框架搭建 (四) 简易有限状态机
  13. AugularJS从入门到实践(二)
  14. Shell脚本数据备份
  15. Typescript基础
  16. Monkey工具
  17. Python面向对象 三大特性 综合案例+1(视频里的作业)
  18. 【java】详解native方法的使用
  19. SharePreferences
  20. 利用mysql行级锁创建数据库主键id

热门文章

  1. vue 图片下载
  2. JS回文检查(FreeCodeCamp项目)
  3. vue高级进阶( 二 ) 8种组件通信详解
  4. win11 改键盘映射
  5. ubuntu 16.04 安装peach
  6. Markdown 基础语法 备忘录
  7. Vulnhub 靶场 HACK ME PLEASE: 1
  8. cublas fp16
  9. K8s网络策略
  10. 敌兵布阵 HDU - 1166 - 单点修改,区间查询:树状数组/线段树