伺服器長期駐留記憶體,對記憶體回收敏感。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 以 常數時間 交換兩個向量的內部指標、大小、容量三個成員,不搬移元素、不配置/釋放記憶體。
#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()` 管理容量預期。