Linux Allocator не освобождает небольшие куски памяти

Распределитель glibc в Linux ведет себя странно. Надеюсь, кто-то может пролить свет на это. Вот исходный файл, который у меня есть:

first.cpp:

#include <unistd.h>
#include <stdlib.h>
#include <list>
#include <vector>

int main() {

  std::list<char*> ptrs;
  for(size_t i = 0; i < 50000; ++i) {
    ptrs.push_back( new char[1024] );
  }
  for(size_t i = 0; i < 50000; ++i) {
    delete[] ptrs.back();
    ptrs.pop_back();
  }

  ptrs.clear();

  sleep(100);

  return 0;
}

second.cpp:

#include <unistd.h>
#include <stdlib.h>
#include <list>

int main() {

  char** ptrs = new char*[50000];
  for(size_t i = 0; i < 50000; ++i) {
    ptrs[i] = new char[1024];
  }
  for(size_t i = 0; i < 50000; ++i) {
    delete[] ptrs[i];
  }
  delete[] ptrs;

  sleep(100);

  return 0;
}

Я компилирую оба:

$ g++ -o first first.cpp
$ g++ -o second second.cpp

Сначала я бегу, и после того, как он спит, я вижу размер резидентной памяти:

Когда я компилирую first.cpp и запускаю его, я смотрю на память с помощью ps:

$ ./first&
$ ps aux | grep first
davidw    9393  1.3  0.3  64344 53016 pts/4    S    23:37   0:00 ./first


$ ./second&
$ ps aux | grep second
davidw    9404  1.0  0.0  12068  1024 pts/4    S    23:38   0:00 ./second

Обратите внимание на размер резидентной памяти. Во-первых, размер резидентной памяти составляет 53016 КБ. во вторых это 1024к. Сначала никогда не освобождали выделения обратно ядру по тем или иным причинам.

Почему первая программа не отдает память ядру, а вторая - нет? Я понимаю, что первая программа использует связанный список, и связанный список, вероятно, размещает некоторые узлы на той же странице, что и данные, которые мы освобождаем. Однако эти узлы должны быть освобождены, поскольку мы отключаем эти узлы, а затем очищаем связанный список. Если вы запустите одну из этих программ через valgrind, она вернется без утечек памяти. Вероятно, происходит то, что память фрагментируется в файле first.cpp, который отсутствует в файле second.cpp. Однако, если вся память на странице освобождается, как эта страница не возвращается обратно ядру? Что нужно для возврата памяти ядру? Как я могу изменить first.cpp (продолжая помещать символы * в список), чтобы освободить память для ядра.

Ответы на вопрос(4)

Ваш ответ на вопрос