LINUX.ORG.RU

определить размер heap процесса

 proc heap


0

3

Приветствую. Подскажите, как посмотреть стандартными средствами(через proc или еще как нибудь) размер аллокируемой динамической памяти процесса и связанными с ним тредами. /proc/`pid`/status или /proc/`pid`/statm конечно информативны, но, к примеру, не показывают при запущенном процессе изминения динамической памяти, т.е. грубо говоря, процесс периодически аллокирует память, а через proc этого я не вижу, точнее, изминений занимаемой памяти heap не изменяется.

И заодно спрошу, как быстро посмотреть, сколько физических страниц памяти процесс занимает?

Спасибо!

в общем виде никак. Но если повезёт, то вся куча (для glibc это куски меньше MMAP_THRESHOLD) будет в /proc/$PID/maps с пометкой [heap]. Всё остальное там же без указания файла (последняя колонка) тоже можно считать динамической памятью.

точнее, изминений занимаемой памяти heap не изменяется.

т.е. хочешь знать сколько из отожранной памяти кучей реально используется. Это точно просто так не посмотришь, нужно смотреть процессу в память и «парсить» структуры кучи.

Либо нужно использовать heap профайлеры (см. valgrind)

mashina ★★★★★
()
Последнее исправление: mashina (всего исправлений: 2)
Ответ на: комментарий от mashina

спасибо мил человек. maps тоже смотрю, размеры heap реально не изменяются, даже явно в приложении каждую секунду по 5 KB аллокирую. вообщем, непонятно, почему просто не могу узнать фактически сколько приложение «потребляет памяти»

plusPlus
() автор топика
Ответ на: комментарий от plusPlus

Виртуально приложение потребляет как раз столько памяти, сколько там написано (~сумма по анонимным rw маппингам). Куча отжирает себе память впрок кусками из чего потом отдаёт память malloc()'ами. Потому твои аллоки по 5кб ничего не меняют.

mashina ★★★★★
()
Последнее исправление: mashina (всего исправлений: 1)
Ответ на: комментарий от mashina

Да я это уже понял. Все равно должен же быть какой то способ узнать, сколько физической памяти процесс потребляет?!

plusPlus
() автор топика
Ответ на: комментарий от plusPlus

malloc может отработать без системных вызовов, так что никто кроме libc не будет знать +5kb там или нет.

Можно подменить malloc & co на уровне линкера — http://stackoverflow.com/q/426230, http://panthema.net/2013/malloc_count/, но это дополнительные тормоза (если существенно).

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

ясно, теперь понятно, почему heap не изменяется.

а как я могу реально узнать кол-во памяти, которое использует процесс? модуль ядра нужен какой то? помогите правильно нагуглить пожалуйста

plusPlus
() автор топика
Ответ на: комментарий от plusPlus

1. Если с точки зрения ядра — http://www.ualberta.ca/CNS/RESEARCH/LinuxClusters/mem.html. Тут только proc, ps, pmap, etc. Не «реально» / не точно с точки зрения логики программы.

2. Либо писать свой учёт памяти, чтобы было «реальнее» с этой точки зрения, грубо говоря, меняем malloc на свою функцию — считаем память, вызываем настоящий malloc. Учитывает это только вызовы malloc, естественно, может быть неточно. Есть готовое — valgrind (vg replace malloc), google perftools — http://google-perftools.googlecode.com/svn/trunk/doc/heapprofile.html (см. замечание про STL), malloc_count, etc. Для языков отличных от C/C++ тоже есть подобное.

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

Если ТС не против, спрошу тут. Как проверить memory leaks с помощью google perftools, если приложение бесконечно долго работает?

kabanchik
()
Ответ на: комментарий от gh0stwizard

Прямо из программы вызов getrusage(2)

Интересно, что в ru_maxrss что-то попадает только при непосредственном использовании, иначе фиктивные выделения памяти дают виртуальную память, что видно только в VmData.

quasimoto ★★★★
()
Ответ на: комментарий от quasimoto

Про vsize как-то забыли, да. Но она считается по-другому. Тогда надо парсить либо statm, либо status (дает в разы больше инфы) и их расплодили тоннами. Кстати, не все файлы из proc одинаково считают и надо лезть в сорцы ядра, чтобы смотреть кто как считает :/

Также есть утилита pmap, которая выдает всю инфу (ключ -x).

gh0stwizard ★★★★★
()
Ответ на: комментарий от gh0stwizard

Кстати, не все файлы из proc одинаково считают и надо лезть в сорцы ядра, чтобы смотреть кто как считает :/

ps, pmap, top, free, pgrep, pkill и т.п. используют libprocps — https://gitorious.org/procps/procps/source/HEAD:proc/readproc.h (proc_t), https://gitorious.org/procps/procps/source/HEAD:proc/readproc.c (status2proc, stat2proc, statm2proc), http://codingrelic.geekhold.com/2011/02/listing-processes-with-libproc.html.

quasimoto ★★★★
()
Ответ на: комментарий от gh0stwizard

Отовсюду, но там утверждается, что rss = resident = vm_rss * 1024 / page_size и size = vm_size * 1024 / page_size, то есть оно просто в разных единицах. Вот так я разницы не увидел:

#include <cstdio>
#include <unistd.h>
#include <proc/readproc.h>

const long page_size = sysconf(_SC_PAGESIZE);

int main() {
    PROCTAB* ps = openproc(PROC_FILLMEM | PROC_FILLSTAT | PROC_FILLSTATUS);
    static proc_t i;
    printf("%*s\t%*s\t%*s\t%*s\t%*s\t%*s\n\n", 10, "process",
           10, "rss", 10, "rss", 10, "rss", 10, "vm_size", 10, "vm_size");
    while (readproc(ps, &i) != 0)
        printf("%10s\t%10ld\t%10ld\t%10ld\t%10ld\t%10ld\n",
               i.cmd,
               i.rss * page_size, i.resident * page_size, i.vm_rss * 1024, // rss
               i.size * page_size, i.vm_size * 1024 // vm_size
              );
}
$ ./a.out
   process	       rss	       rss	       rss	   vm_size	   vm_size

      init	    712704	    712704	    712704	   4337664	   4337664
...
$ strace ./a.out 2>&1 | grep proc
...
stat("/proc/1", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/1/stat", O_RDONLY)          = 4
open("/proc/1/statm", O_RDONLY)         = 4
open("/proc/1/status", O_RDONLY)        = 4
...

ну а «реально» оно где-то между, в разбросе.

quasimoto ★★★★
()
Последнее исправление: quasimoto (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.