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 <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()釋放額外的預分配內存。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM