Измерять статическую, кучную и стековую память? (C++, Linux - Centos 7)

Я хотел бы измерить стек, кучу и статическую память отдельно, потому что у меня есть некоторые ограничения для каждого из них.

Для измерения кучи памяти я использую инструмент valgrind->massif. Массив также должен быть в состоянии измерить кучу и память стека, но он показывает странные результаты:

  • Последний снимок без --stacks=yes обеспечивает общее (B)=0, полезную кучу (B)=0, дополнительную кучу (B)=0 (так что все в порядке)

  • Последний снимок с параметром --stacks=yes обеспечивает общее (B)= 2256, полезную кучу (B)=1,040, дополнительную кучу (B)=0, стеки (B)=1,208 (что показывает утечку памяти, даже если это та же команда и тот же бинарный тест... не знаю почему...)

Итак, наконец, мне нужен инструмент для измерения стека и статической памяти, используемой двоичным файлом с ++, некоторая помощь будет приветствоваться:)

Спасибо за вашу помощь!

----------- РЕДАКТИРОВАТЬ --------------

В дополнение к комментарию Basile Starynkevitch, чтобы объяснить, что я имею в виду со статической, стековой и кучной памятью, я взял это из документации библиотеки Dmalloc:

  • Статические данные - это информация, пространство хранения которой компилируется в программу.

    /* global variables are allocated as static data */
    int numbers[10];
    
    main()
    {
            …
    }
    
  • Данные стека - это данные, выделяемые во время выполнения для хранения информации, используемой внутри функций. Эти данные управляются системой в пространстве, называемом пространством стека.

    void foo()
    {
            /* if they are, the parameters of the function are stored in the stack */
            /* this local variable is stored on the stack */
            float total;
            …
    }
    
    main()
    {
        foo();
    }
    
  • Данные кучи также выделяются во время выполнения и предоставляют программисту возможности динамической памяти.

    main()
    {
        /* the address is stored on the stack */
        char * string;
        …
    
        /*
         * Allocate a string of 10 bytes on the heap.  Store the
         * address in string which is on the stack.
         */
        string = (char *)malloc(10);
        …
    
        /* de-allocate the heap memory now that we're done with it */
        (void)free(string);
        …
    }
    

2 ответа

Я хотел бы измерить стек, кучу и статическую память отдельно, потому что у меня есть некоторые ограничения для каждого из них.

Я не могу себе представить, почему у вас есть отдельные ограничения для каждого. Все они сидят в виртуальной памяти! Кстати, вы можете использовать setrlimit (2) для установки ограничений (возможно, из вызывающего процесса оболочки, например, с помощью bash ulimit встроено в него).

Ваши определения наивны, если вы учитываете фактическое виртуальное адресное пространство вашего процесса.

Кстати, proc (5) позволяет запрашивать это пространство, например, используя /proc/self/maps как здесь из вашей программы (или /proc/1234/maps запросить процесс pid 1234, возможно, из терминала). Вы также можете использовать /proc/self/status а также /proc/self/statm (Кстати, попробуйте cat /proc/self/maps а также cat /proc/$$/maps в терминале). В Linux вы также можете использовать mallinfo(3) и malloc_stats(3), чтобы получить информацию о статистике выделения памяти.

Статические данные могут находиться в сегменте данных (или сегменте BSS) вашей программы. Но как насчет локального пространства потока? И эти сегменты данных также содержат данные, внутренние для различных библиотек, в частности, стандартной библиотеки C libc.so (это считается?). Конечно, сегмент стека часто больше (так как страница выровнена), чем фактически используемый стек (от "низа" до текущего %esp регистр). А многопоточный процесс имеет несколько стеков (и сегментов стека), по одному на поток.

Данные стека, конечно, находятся в стеке вызовов, который содержит много других вещей (адреса возврата, промежуток, разлитые регистры), а не только автоматические переменные (некоторые из них находятся только в регистрах или оптимизируются компилятором, не занимая слот стека).). Они считают? Кроме того, код запуска от crt0 (который вызывает ваш main), вероятно, будет использовать немного стекового пространства (это считается?)...

Данные, выделенные из кучи (они могут быть выделены из различных библиотек или даже из динамического компоновщика), содержат не только то, что получает ваша программа malloc (и друзья) но и необходимые накладные расходы. Это считается? А как насчет файлов с отображенной памятью? Как они должны рассчитывать?

Я бы порекомендовал запросить фактическое виртуальное адресное пространство (например, читая /proc/self/maps или используя pmap (1)...), но вы получите нечто отличное от того, что вы просите.

Просто, кстати, я нашел это перед вашим ответом:

  • Для измерения кучи памяти используйте valgrind -> массив

  • Для измерения статической памяти используйте функцию bash size на двоичном

  • Для измерения стека можно использовать стек

Это дало мне всю статистику, которую я хотел

Другие вопросы по тегам