linux内核源码解析:linux源码下载及top命令中的RES是如何计算的
linux源码 -> linux/fs/proc/task_mmu.c -> task_statm() -->> *resident = *shared + get_mm_counter(mm, MM_ANONPAGES); *shared = get_mm_counter(mm, MM_FILEPAGES); static inline unsigned long get_mm_counter(struct mm_struct *mm, int member) { long val = atomic_long_read(&mm->rss_stat.count[member]); #ifdef SPLIT_RSS_COUNTING /* * counter is updated in asynchronous manner and may go to minus. * But it's never be expected number for users. */ if (val < 0) val = 0; #endif return (unsigned long)val; }
#include <stdio.h> #include <stdint.h> //#include <sys/types.h> //#include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #define page_map_file "/proc/self/pagemap" #define PFN_MASK ((((uint64_t)1)<<55)-1) #define PFN_PRESENT_FLAG (((uint64_t)1)<<63) int mem_addr_vir2phy(unsigned long vir, unsigned long *phy) { static int fd_init = 0; static int fd; unsigned long page_size=getpagesize(); unsigned long vir_page_idx = vir/page_size; unsigned long pfn_item_offset = vir_page_idx*sizeof(uint64_t); uint64_t pfn_item; if(fd_init == 0) { fd = open(page_map_file, O_RDONLY); fd_init = 1; } if (fd<0) { close(fd); fd_init = 0; //printf("open %s failed\n", page_map_file); return -1; } if ((off_t)-1 == lseek(fd, pfn_item_offset, SEEK_SET)) { close(fd); fd_init = 0; //printf("lseek %s failed", page_map_file); return -1; } if (sizeof(uint64_t) != read(fd, &pfn_item, sizeof(uint64_t))) { close(fd); fd_init = 0; //printf("read %s failed", page_map_file); return -1; } if (0==(pfn_item & PFN_PRESENT_FLAG)) { //printf("page is not present"); return -1; } *phy = (pfn_item & PFN_MASK)*page_size + vir % page_size; return 0; } void mem_addr_vir2phy_test(void) { int mem_addr_vir2phy(unsigned long vir, unsigned long *phy); unsigned long phy_address; int size0 = 1024*1024*32; char *pMem0 = (char*)malloc(size0); for(int Index = 0; Index < size0; Index+=MB(1)/16) { int ret = mem_addr_vir2phy((unsigned long)pMem0 + Index, &phy_address); if(ret == 0) printf("Mem0.malloc %016llX + %2d.%04d MB -> %016llX (%d)\n", pMem0, Index/MB(1), (Index%MB(1))/1024, phy_address, ret); } for(int Index = 0; Index < 8; Index++)printf("--------- ");printf("\n"); for(int Index = MB(1); Index < MB(1)+1024; Index++) { pMem0[Index] = 1; } for(int Index = 0; Index < size0; Index+=MB(1)/16) { int ret = mem_addr_vir2phy((unsigned long)pMem0 + Index, &phy_address); if(ret == 0) printf("Mem1.malloc %016llX + %2d.%04d MB -> %016llX (%d)\n", pMem0, Index/MB(1), (Index%MB(1))/1024, phy_address, ret); } for(int Index = 0; Index < 8; Index++)printf("--------- ");printf("\n"); system("top -n 1 -p `pidof test01`|grep test01"); for(int Index = 0; Index < 8; Index++)printf("--------- ");printf("\n"); for(int Index = 0; Index < size0; Index++) { pMem0[Index] = Index; } system("top -n 1 -p `pidof test01`|grep test01"); for(int Index = 0; Index < 8; Index++)printf("--------- ");printf("\n"); return ; }