首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

STL 容器記憶體緊縮技巧:vector::swap(idiom) 釋放多餘容量

     編輯:關於C語言

伺服器長期駐留記憶體,對記憶體回收敏感。STL 容器 (如 vector) 為了效能採用容量增長不縮減策略:push_back 10,000 個元素後 pop_back 全部移除,已配置記憶體不會自動釋放,`capacity()` 維持高位。若確實需要歸還記憶體給系統,可使用 swap-with-temporary 慣用語。

核心技法:vector<T>().swap(vec)


std::vector<Block> vec;
// ... 大量 push_back/pop_back 操作 ...
// 此時 vec.size() == 0 但 vec.capacity() 很大

std::vector<Block>().swap(vec);  // 關鍵一行
// vec 現為空容器且 capacity() == 0
// 臨時物件析構時釋放原本 vec 持有的記憶體塊

原理說明

  • vector::swap 以 常數時間 交換兩個向量的內部指標、大小、容量三個成員,不搬移元素、不配置/釋放記憶體。
  • 建立臨時空向量 `vector<Block>()`,其 `capacity() == 0`。
  • 交換後,原向量變成空且無容量;臨時向量持有原本的大記憶體塊。
  • 臨時向量在完整表達式結束時立即析構,釋放記憶體回堆/作業系統。

完整示範程式


#include <vector>
#include <iostream>

using namespace std;

struct Block { char dummy[1024]; };  // 1 KB 區塊
typedef vector<Block> BlkVector;

void show_space(BlkVector *v) {
    cout << "size = " << v->size()
         << ", capacity = " << v->capacity() << endl;
}

int main() {
    BlkVector bv;
    Block b;
    show_space(&bv);                 // size=0, cap=0
    bv.push_back(b);
    show_space(&bv);                 // size=1, cap=1
    for (int i=0; i<1000; ++i) bv.push_back(b);
    show_space(&bv);                 // size=1001, cap=1024 (擴充策略)
    while (!bv.empty()) bv.pop_back();
    show_space(&bv);                 // size=0, cap=1024 (記憶體未釋放)
    BlkVector().swap(bv);              // 緊縮!
    show_space(&bv);                 // size=0, cap=0 (記憶體已歸還)
    return 0;
}

適用場景與注意事項

場景建議
長期運行的服務、記憶體受限嵌入式系統定期或於記憶體壓力時呼叫 `swap` 釋放
高頻配置/釋放的迴圈避免頻繁 swap,改用 `reserve()` 預留或物件池
C++11 及以上可改用 vec.shrink_to_fit() (非強制性請求)
迭代器/指標/引用有效性swap 後全失效,使用前確保無殘留引用

標準庫參考


void swap(vector<T,Allocator>& vec);  // 成員函式
// 全域算法同名函式 std::swap(v1, v2) 行為一致

結論:`vector<T>().swap(vec)` 是 C++98/03 時代釋放 `vector` 多餘容量的標準慣用語,C++11 建議改用 `shrink_to_fit()` 並配合 `reserve()` 管理容量預期。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved