Почему размер VmData в Linux больше, чем оценка из кода?

#c #linux #gcc #memory

#c #linux #gcc #память

Вопрос:

Я хочу знать, сколько памяти займет выполнение кода. Я суммирую всю память, используемую в моем коде, и использую GCC для преобразования в исполняемый файл bin.

Когда я запускаю файл bin и использую cat/proc/$PID/status , VmSize VmData намного больше, чем ожидалось. Даже если удалить весь код, а только перейти в режим ожидания, результат все равно останется тем же,

 VmPeak:    12816 kB
VmSize:    12816 kB
VmLck:         0 kB
VmPin:         0 kB
VmHWM:       964 kB
VmRSS:       964 kB
VmData:      204 kB
VmStk:       136 kB
VmExe:        56 kB
VmLib:      2100 kB
VmPTE:        48 kB
VmPMD:        12 kB
VmSwap:        0 kB
  
  • Почему память такая большая, даже если в моем коде нет данных? данные, которые я оцениваю в коде, должны составлять не более 40 КБ, но VmData составляет 204 КБ, что намного больше…
  • Почему VmData одинаковы независимо от того, добавляю я #if 0 в коде или нет? Почему бы не изменить размер при добавлении? Я думаю, что, по крайней мере, должно быть на 30 КБ меньше…
  • как получить память, которую точно использует мой код? Есть другие способы тестирования?
 #include <stdio.h>


int main()
{
    #if 0 
    extern int ed25519_getpub(unsigned char* public_key, const unsigned char* private_key);
    extern int ed25519_sign(unsigned char* signature,
                    const unsigned char* private_key,
                    const unsigned char* msg, const unsigned long msg_len); // use a large static global 30K array
    extern int ed25519_verify(const unsigned char* signature,
                      const unsigned char* public_key,
                      const unsigned char* msg, const unsigned long msg_len); // use the same 30K array

    int ret = 0;
    unsigned char public_key[32];
    unsigned char private_key[32] = "123456789ABC";
    unsigned char signature[64];
    unsigned char msg[64] = "abcdefghijklmnopqrstuvwxyz";
    sleep(20);
    #endif

    for (int i = 0; i < 1000000; i  )
    {
        #if 0 
        //compute public key
        ret = ed25519_getpub( public_key, private_key );
        if (0 != ret)
        {
            ret = 1;
        }

        printf("public_key = %s, ret = %d rn ", public_key, ret);

        ret = ed25519_sign( signature, private_key, msg, strlen(msg) );
        if (0 != ret)
        {
            ret = 2;
        }

        printf("signature = %s, ret = %d, rn", signature, ret);

        //verify sign
        ret = ed25519_verify( signature, public_key, msg, strlen(msg) );
        if (0 != ret)
        {
            ret = 3;
        }

        printf("ed25519_verify ret = %d, rn ", ret);
        #endif

        if (0 == (i % 5 ))
        {
            sleep(10);
        }
    }

    return 0;
}
  

Комментарии:

1. предлагаю вам начать с публикации кода, который вызывает у вас проблему. В противном случае, как, по-вашему, мы можем помочь вам отладить проблему?

2. хорошо, код опубликован

3. в опубликованном коде отсутствует оператор the: #include <unistd.h> , необходимый для предоставления прототипа функции: sleep()

Ответ №1:

эта масса кода сводится к: (потому что большая его часть устраняется с помощью `#if 0″ … Последовательности ‘#endif’)

 #include <unistd.h> // for the 'sleep()' function


int main( void )
{
    for (int i = 0; i < 1000000; i  )
    {
        if ( 0 == (i % 5 ) )
        {
            sleep(10);
        }
    }
}
  

где: я компилирую на ubuntu linux 18.02

вот как я скомпилировал код:

 gcc -ggdb -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled2.c" 
  

вот как я связал код:

 gcc -ggdb -Wall -o "untitled2" "untitled2.c"
  

Примечание: -ggdb это делается для того, чтобы код содержал максимальную отладочную информацию для gdb отладчика

после компиляции / компоновки результирующий размер исполняемого файла можно определить с помощью:

  ls -al untitled2.c
  

что приводит к:

  -rwxrwxrwx 1 richard richard 182 Mar  4 20:54 untitled2.c
  

182 байта не похожи ни на 204, ни на 40 кб

Пожалуйста, опубликуйте свой компилятор, свою ОС и скомпилировали ли вы link в dynamic (по умолчанию) исполняемый файл или в static исполняемый файл

Комментарии:

1. когда вы отметите ответ, оставьте комментарий о том, почему

2. объем памяти во время выполнения будет зависеть от нескольких факторов. в том числе: 1) находятся ли необходимые библиотечные функции уже в памяти, какой длины стек, сколько памяти файловой области выделяет ОС и многое другое в целом, бессмысленное число, которое может меняться в зависимости от внешних обстоятельств