Com que rapidez / frequência as medições de memória de processo são atualizadas no kernel?

1

Em sua resposta à pergunta Como freqüentemente é o sistema de arquivos proc atualizado no Linux? , Jonathan Ben-Avraham disse que /proc/.../statm é atual assim que você o lê, pois a leitura diretamente ativa os retornos de chamada do kernel.

E os dados lidos por esses retornos de chamada do kernel? Isso está sempre correto ou existe algum atraso entre a memória solicitada do malloc / new e o kernel disponibilizando a medição para uso por /proc/.../statm ?

Estou tentando encontrar um método para medir o tamanho atual dos objetos alocados via malloc ou new .

Executando um pequeno programa de teste que aloca alguns dados, nem /proc/.../statm nem chamando sbrk() parece se correlacionar imediatamente com a quantidade de memória alocada pelo processo.

Não há como obter informações precisas?

PROGRAMA DE ALOCAÇÃO de blocos de 64 KB e 128 KB

$ ./a.out
MALLOC TEST. Size = 131072
0 ALLOC: HEAP SIZE: 0   MEMORY USAGE (statm): 1083 201 173 2 0 341 0
1 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1083 211 182 2 0 341 0
2 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1116 215 185 2 0 374 0
3 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1149 216 185 2 0 407 0
4 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1182 217 185 2 0 440 0
5 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1215 218 185 2 0 473 0
6 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1248 219 185 2 0 506 0
7 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1281 220 185 2 0 539 0
8 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1314 221 185 2 0 572 0
9 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1347 222 185 2 0 605 0

$ ./a.out
MALLOC TEST. Size = 65536
0 ALLOC: HEAP SIZE: 0   MEMORY USAGE (statm): 1067 201 174 2 0 325 0
1 ALLOC: HEAP SIZE: 0   MEMORY USAGE (statm): 1067 211 182 2 0 325 0
2 ALLOC: HEAP SIZE: 0   MEMORY USAGE (statm): 1067 215 185 2 0 325 0
3 ALLOC: HEAP SIZE: 196608  MEMORY USAGE (statm): 1115 216 185 2 0 373 0
4 ALLOC: HEAP SIZE: 196608  MEMORY USAGE (statm): 1115 217 185 2 0 373 0
5 ALLOC: HEAP SIZE: 196608  MEMORY USAGE (statm): 1115 218 185 2 0 373 0
6 ALLOC: HEAP SIZE: 393216  MEMORY USAGE (statm): 1163 219 185 2 0 421 0
7 ALLOC: HEAP SIZE: 393216  MEMORY USAGE (statm): 1163 220 185 2 0 421 0
8 ALLOC: HEAP SIZE: 393216  MEMORY USAGE (statm): 1163 221 185 2 0 421 0
9 ALLOC: HEAP SIZE: 589824  MEMORY USAGE (statm): 1211 222 185 2 0 469 0

PROGRAMA DE TESTE

class CfgProfileList
{
public:
    bool obtainSystemProfileList();
    void leakTest();
    void leakObjTest();
    std::set<std::string> mProfileList;
private:
    char dummy[1024 * 1024]; // use up some space
};

class ComUtil
{
public:
    static void printMemoryUsage();

private:
    static unsigned int mHeapOrigin;
};

/* static */
unsigned int ComUtil::mHeapOrigin = 0;

// Print current process memory utilization
/* static */ void
ComUtil::printMemoryUsage()
{
    unsigned int pHeap = (unsigned int)sbrk(0);
    if (mHeapOrigin == 0)
        mHeapOrigin = pHeap;

    printf("HEAP SIZE: %u\t", pHeap - mHeapOrigin);

    char fname[256], line[256];
    sprintf(fname, "/proc/%d/statm", getpid());

    FILE *pFile = fopen(fname, "r");
    if (!pFile)
        return;

    fgets(line, 255, pFile);
    fclose(pFile);
    printf("MEMORY USAGE (statm): %s", line);
}



void
CfgProfileList::leakTest()
{
    char *pointerList[50];
    int  n = 10;
    int  sleep = 1; 
    int  size  = 64 * 1024;

    printf("MALLOC TEST. Size = %d\n", size);

    for (int i = 0; i < n; i++)
    {
        pointerList[i] = (char *)malloc(size);
        printf("%d ALLOC: ", i);
        ComUtil::printMemoryUsage();
        usleep(sleep);
    }
}

int
main(int argc, char **argv)
{
    CfgProfileList pl;
    pl.leakTest();
}
    
por Danny 12.12.2016 / 09:02

1 resposta

1

Seus traços parecem mais adequados para mim ... (lembre-se de que há um heap inicial que seu código não mede.)

MALLOC TEST. Size = 131072

Aqui você está alocando blocos de 128 KB, então o alocador provavelmente não usará sbrk() , mas mmap() .

0 ALLOC: HEAP SIZE: 0   MEMORY USAGE (statm): 1083 201 173 2 0 341 0
1 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1083 211 182 2 0 341 0

Este é o ímpar, o seu heap aumenta, mas não as páginas do programa.

2 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1116 215 185 2 0 374 0
3 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1149 216 185 2 0 407 0
4 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1182 217 185 2 0 440 0
5 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1215 218 185 2 0 473 0
6 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1248 219 185 2 0 506 0
7 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1281 220 185 2 0 539 0
8 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1314 221 185 2 0 572 0
9 ALLOC: HEAP SIZE: 135168  MEMORY USAGE (statm): 1347 222 185 2 0 605 0

Aqui, cada alocação consome 33 páginas extras, ou 132 KB, e tudo está OK.

MALLOC TEST. Size = 65536
0 ALLOC: HEAP SIZE: 0   MEMORY USAGE (statm): 1067 201 174 2 0 325 0
1 ALLOC: HEAP SIZE: 0   MEMORY USAGE (statm): 1067 211 182 2 0 325 0
2 ALLOC: HEAP SIZE: 0   MEMORY USAGE (statm): 1067 215 185 2 0 325 0

Aqui suas alocações cabem no heap inicial.

3 ALLOC: HEAP SIZE: 196608  MEMORY USAGE (statm): 1115 216 185 2 0 373 0
4 ALLOC: HEAP SIZE: 196608  MEMORY USAGE (statm): 1115 217 185 2 0 373 0
5 ALLOC: HEAP SIZE: 196608  MEMORY USAGE (statm): 1115 218 185 2 0 373 0

O heap recebe uma variação de 192 KB, que corresponde às páginas alocadas e cabe três alocações.

6 ALLOC: HEAP SIZE: 393216  MEMORY USAGE (statm): 1163 219 185 2 0 421 0
7 ALLOC: HEAP SIZE: 393216  MEMORY USAGE (statm): 1163 220 185 2 0 421 0
8 ALLOC: HEAP SIZE: 393216  MEMORY USAGE (statm): 1163 221 185 2 0 421 0

O mesmo novamente ...

9 ALLOC: HEAP SIZE: 589824  MEMORY USAGE (statm): 1211 222 185 2 0 469 0

... e novamente.

A execução com strace -e brk,mmap ajudará a entender as coisas. As informações disponíveis em sbrk() e /proc são precisas, sem demora.

    
por 12.12.2016 / 09:19

Tags