cgroup memory usage statistic

| 分类 Linux  | 标签 memory  cgroup 

之前写过一篇cgroup内存统计的文章,这里再做一些补充。

几个内存统计相关的变量:

  • cache - # of bytes of page cache memory.

    file cache,包括shm page

  • rss - # of bytes of anonymous and swap cache memory (includes transparent hugepages).

    包括所有的anon page和swap cache page

  • mapped_file - # of bytes of mapped file (includes tmpfs/shmem)

    当前页表正在映射文件的page(包括shm page)

  • inactive_anon - # of bytes of anonymous and swap cache memory on inactive LRU list.

    inactive LRU,包括anon page和swap cache page

  • active_anon - # of bytes of anonymous and swap cache memory on active LRU list.

  • inactive_file - # of bytes of file-backed memory on inactive LRU list.

    inactive LRU,file page

  • active_file - # of bytes of file-backed memory on active LRU list.

从统计的角度,内核将page分成四类:

(1)anon page:比如malloc分配的page。这类page会影响rss、inactive_anon(active_anon)

(2)file mapped page:文件映射的page,比如通过mmap映射文件。这类page会影响cache、inactive_file(active_file)

(3)shm page:影响cache、inactive_anon(active_anon)

(4)swap cache page:影响rss、inactive_anon(active_anon)

实际上:

cache: file cache page + shm page
rss:  anonymous page + swap cache page
(in)active_anon: anonymous page + swap cache page + shm page
(in)active_file: file cache page

rss + cache = (in)active_anon + (in)active_file

anon page

从上面可以看出,当发生缺页时,如果是anon page,内核会分配一个page,影响rss和active_anon。

示例:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define BUF_SIZE 4000000000   

int main(int argc,char **argv){
    char *shmptr = (char*) malloc(BUF_SIZE);
    memset(shmptr,'\0',1000000000);

    printf("sleep...\n");
    while(1)
        sleep(1);

    exit(0);
}

测试前

cache 59232256
rss 7950336
mapped_file 8232960
inactive_anon 2633728
active_anon 7958528
inactive_file 37187584
active_file 19402752

测试后

cache 59232256
rss 1007697920
mapped_file 8216576
inactive_anon 2633728
active_anon 1007706112
inactive_file 37158912
active_file 19431424

可以看到,rss和active_anon发生了变化。

file mapped page(include shm)

当发生缺页时,如果page是映射文件的page,会分配page,并从磁盘(tmpfs)读取对应的数据,影响cache、(in)active_file。严格来说,shm没有磁盘文件,但shm建立在tmpfs之上,所以,内核也将其与文件同等对待,但page会加到(in)active_anon LRU list。

示例:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define BUF_SIZE 4000000000   
#define MYKEY 26 

int main(int argc,char **argv){
    int shmid;
    char *shmptr;

    if((shmid = shmget(MYKEY,BUF_SIZE,IPC_CREAT)) ==-1){
        fprintf(stderr,"Create Share Memory Error0m~Z%s\n\a",strerror(errno));
        exit(1);
    }

    if((shmptr =shmat(shmid,0,0))==(void *)-1){
        printf("shmat error!\n");
        exit(1);
    }

    memset(shmptr,'\0',1000000000);

    printf("sleep...\n");
    while(1)
        sleep(1);

    exit(0);
}

程序运行前:

cache 65875968
rss 7643136
mapped_file 8273920
inactive_anon 2633728
active_anon 7651328
inactive_file 43126784
active_file 20107264

程序运行中:

cache 1065881600
rss 7729152
mapped_file 1008279552
inactive_anon 1002635264
active_anon 7737344
inactive_file 43118592
active_file 20119552

程序运行后:

cache 1066213376
rss 7852032
mapped_file 8404992
inactive_anon 1002635264
active_anon 7860224
inactive_file 43356160
active_file 20213760

可以看到,共享内存的分配影响cache、inactive_anon和mapped_file。但值得注意的是,当程序退出之后,mapped_file减小,但inactive_anon并没有变。

实际上,mapped_file表示当前内存页表当前正在映射的page,由于进程退出,页表映射取消,但page并没有free或者swap out,所以inactive_anon不变。

swap cache page

当发生缺页时,如果page对应交换分区,会分配page,并从swap读取数据,影响rss和(in)active_anon。

另外,注意swap cache与(file)cache的区别,前者用于anon page换出时保存数据,后者指file cache page(include shm)。


上一篇     下一篇