%20%D0%BF%D1%80%D0%BE%D1%86%D0%B5%D1%81%D1%81%D0%BE%D0%BC%20%D0%B2%20Linux.png)
Я знаю, что если процесс выполняет операцию, malloc()
но на самом деле не записывает данные в эту память, Linux считает, что эта память свободна и может использоваться другими процессами (перерасход памяти).
В любом случае, есть ли способ узнать, сколько памяти было malloc()
использовано данным процессом? (даже если он не использовался)
Эта информация существует в масштабе всей системы /proc/meminfo
, но мне хотелось бы узнать ее для конкретного процесса.
Я покопался /proc/<PID>/{smaps,stat,statm}
, но не уверен, что там отображается эта информация.
решение1
Вызовы malloc()
, которые приводят к изменению размера сегмента данных (то есть, которые не используют повторно ранее выделенную память — поэтому выделения, которые приводят к вызовам sbrk()
или mmap()
), отображаются в /proc/$PID/statm
и /proc/$PID/stat
.
В statm
первом поле отображается общий размер программы, а в шестом поле отображается количество страниц данных; оба поля отражают распределение памяти (даже если она не используется).
В stat
поле, на которое нужно обратить внимание, есть vsize
(в настоящее время это 23-е поле).
(См. таблицы 1-3 и 1-4 вproc
документация.)
Обратите внимание, что они показывают общее использование памяти и общие размеры сегментов данных, поэтому вы не можете отличить использованную память от malloc()
другого использования памяти.
Вы можете увидеть это в действии с помощью следующей программы:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv) {
void *buf;
puts("Waiting before allocating...");
sleep(20);
buf = malloc(10*1024*1024*1024L);
puts("Sleeping after allocating...");
sleep(20);
free(buf);
return 0;
}
(Как всегда, отличная обработка ошибок.) Затем
$ ./356532&
[1] 4239
Waiting before allocating...
$ cat /proc/4239/statm
1043 172 154 1 0 81 0
$ cat /proc/4239/stat | awk '{print $23}'
4272128
Sleeping after allocating...
$ cat /proc/4239/statm
2622484 172 154 1 0 2621522 0
$ cat /proc/4239/stat | awk '{print $23}'
10741694464
Эндрю Хенле указал malloc_info(3)
, и вы можете использовать это практически в любом процессе. Используя пример программы выше,без какой-либо отладочной информации(просто чтобы показать, что это не обязательно):
$ gdb ./356532
> break free
(это устанавливает точку останова при вызове free
в программе — на самом деле, при любом вызове free
, но сначала мы выполним «наш»; попытка сделать это с помощью malloc
не будет столь полезной, поскольку код запуска использует malloc
)
> run
При gdb
достижении точки останова можно вызвать malloc_info
так:
> call malloc_info(0, stdout)
Это приведет к сбросу malloc
информации.