Джеймс, In silico и Макс все правы в своих замечаниях. Вы ожидаете, что память будет освобождена при вызове batch.swap(tmp)
, поскольку tmp
пусто. Я только что запустил вашу программу на 64-битном Linux, скомпилированную с помощью gcc 4.6.0. При наблюдении за потреблением памяти сверху, уходит 2 ГБ -> 1,8 ГБ -> 1,8 ГБ. Однако при добавлении batch2
и заполнении его после pause 2
, как при заполнении batch
, потребление памяти не увеличивается. Запуск версии, в которой batch.swap(tmp)
закомментирован, таким образом, фактически имея два огромных вектора, потребление памяти составляет 2 ГБ -> 3,2 ГБ -> 2,8 ГБ -> 2,8 ГБ.
Вот полный код с добавленной опцией командной строки:
#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
typedef unsigned long long int64;
int main(int argc, char** argv)
{
bool no_swap = (argc > 1 && strcmp(argv[1], "-noswap") == 0);
{
vector<vector<int64> > batch;
vector<vector<int64> > batch2;
{
vector<int64> v;
for (size_t i = 0; i < 12; ++i)
v.push_back(8000000000);
for (size_t i = 0; i < 10000000; ++i)
batch.push_back(v);
}
cout << "pause 1" << endl;
cin.ignore();
{
vector<vector<int64> > tmp;
if (no_swap) {
cout << "NOT calling batch.swap(tmp)" << endl;
} else {
cout << "calling batch.swap(tmp)" << endl;
batch.swap(tmp);
}
}
cout << "pause 2" << endl;
cin.ignore();
{
vector<int64> v2;
for (size_t i = 0; i < 12; ++i)
v2.push_back(8000000000);
for (size_t i = 0; i < 10000000; ++i)
batch2.push_back(v2);
}
cout << "pause 3" << endl;
cin.ignore();
}
cout << "pause 4" << endl;
cin.ignore();
}
Некоторое объяснение этого поведения можно найти здесь и здесь . Из последнего:
При использовании распределитель может распределять и освобождать, используя стратегии, определенные реализацией.
и эвристика. Из-за этого каждый вызов элемента allocate объекта allocator
функция может не вызывать глобальный оператор new. Эта ситуация также
дублируется для вызовов функции-члена освобождения.
Согласно этому документу, кэширование можно отключить, установив GLIBCXX_FORCE_NEW
, но у меня это не работает ...