Tomsk Sysadmins Forum

Unix => Программирование => Topic started by: Kavka on March 06, 2009, 11:33:59

Title: Выделение-освобождение памяти
Post by: Kavka on March 06, 2009, 11:33:59
Вопрос можно продемонстрировать вот на таком коде
Code: [Select]
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

int                 a;
void *              ptr[65536];

int main() {
   for(a=0;a<10000;a++){
     ptr[a]=malloc(16384); //163 840 000
     usleep(1000);
   }

   for(a=0;a<10000;a++){
     free(ptr[a]);
     usleep(1000);
   }
}

Запускаю прогу и наблюдаю в top как растёт объём занимаемой прогой памяти, пока работает первая часть.
А когда работает вторая часть объём не уменьшается.

Вопрос: что нужно сделать чтобы (по возможности) освободить незадействованную память "кучи" в пользу системы, чтобы объём памяти показываемой в top уменьшился?
Title: Выделение-освобождение памяти
Post by: nuclight on March 06, 2009, 14:07:44
А она и так не задействована и существует чисто номинально - к ней не было обращений (можете проверить по значению общих счетчиков вверху top). Ибо в современных ОС память давно виртуальная. Реально выделена только некоторая ее часть, к которой обращалась библиотечная реализация самого malloc(), поскольку она выделена только что, то вся еще присутствует в ОЗУ, то есть ее размер можно оценить по колонке RES. Дальше уже дело конкретных версий библиотек - на SLES 10 (glibc-2.4-31.2) у меня VIRT/RES был 159m/39m, на FreeBSD 6.2 - 158m/724k.
Title: Выделение-освобождение памяти
Post by: rPman on March 06, 2009, 14:12:13
добавить от себя чтоли вопрос, а если после выделения заполнять память чем-нибудь? В смысле как заставить библиотеку освободить память.
Title: Выделение-освобождение памяти
Post by: nuclight on March 10, 2009, 18:11:50
Если память чем-нибудь заполнить, то программа просто начнет жрать еще больше, на освобождение это не повлияет. Как заставить библиотеку - ну это в документации к библиотеке. Системные интерфейсы для этого имеются (madvise(2) например), но их в обход библиотеки использовать не следует, она потом удивится несоответствию данных, будут непредсказуемые глюки.
Ну и в конце концов, случай программы всё же весьма синтетический - реальные приложения вот таким макаром память не едят, они освобождают, потом снова запрашивают, так что нет смысла ее системе возвращать. На FreeBSD 7, например, эта программа вернет память перед выходом, если ее модифицировать - поставить после финального цикла задержку в несколько десятков секунд и еще какие-нибудь действия. Не ходите против оптимизаций системщиков, пока вам это действительно на практике не понадобилось.