linux 通过mm_struct 获取进程内存占用信息

#include <sys/resource.h>
#include <iostream>
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/mm.h>

using namespace std;



struct mm_struct *get_mm_struct_by_pid(pid_t pid)
{
    struct task_struct *task;
    struct mm_struct *mm;

    task = pid_task(find_vpid(pid), PIDTYPE_PID);
    if (!task)
        return NULL;

    mm = task->mm;
    if (!mm)
        return NULL;

    return mm;
}

void outputMM_Struct(struct mm_struct* mm) {
    unsigned long text, lib, swap, ptes, pmds, anon, file, shmem;
    unsigned long hiwater_vm, total_vm, hiwater_rss, total_rss;

    anon = get_mm_counter(mm, MM_ANONPAGES);
    file = get_mm_counter(mm, MM_FILEPAGES);
    shmem = get_mm_counter(mm, MM_SHMEMPAGES);

    hiwater_vm = total_vm = mm->total_vm;
    if (hiwater_vm < mm->hiwater_vm)
        hiwater_vm = mm->hiwater_vm;
    hiwater_rss = total_rss = anon + file + shmem;
    if (hiwater_rss < mm->hiwater_rss)
        hiwater_rss = mm->hiwater_rss;

    text = (PAGE_ALIGN(mm->end_code) - (mm->start_code & PAGE_MASK)) >> 10;
    lib = (mm->exec_vm << (PAGE_SHIFT-10)) - text;
    swap = get_mm_counter(mm, MM_SWAPENTS);
    ptes = PTRS_PER_PTE * sizeof(pte_t) * atomic_long_read(&mm->nr_ptes);
    pmds = PTRS_PER_PMD * sizeof(pmd_t) * mm_nr_pmds(mm);


    printf("VmPeak:\t%8lu kB\n", hiwater_vm);//------------------------------------虚拟内存使用量的峰值,取mm->total_vm和mm->hiwater_vm的大值。
    printf("VmSize:\t%8lu kB\n", total_vm);//------------------------------------当前虚拟内存的实际使用量。
    printf("VmLck:\t%8lu kB\n", mm->locked_vm);//-------------------------------------PG_mlocked属性的页面总量,常被mlock()置位。
    printf("VmPin:\t%8lu kB\n", mm->pinned_vm);//-------------------------------------不可被移动的Pined Memory内存大小。
    printf("VmHWM:\t%8lu kB\n", hiwater_rss);//-------------------------------------HWM是High Water Mark的意思,表示rss的峰值。
    printf("VmRSS:\t%8lu kB\n", total_rss);//-------------------------------------应用程序实际占用的物理内存大小,这里和VmSize有区别。VmRss要小于等于VmSize。
    printf("RssAnon:\t%8lu kB\n", anon);//-----------------------------------匿名RSS内存大小。
    printf("RssFile:\t%8lu kB\n", file);//-----------------------------------文件RSS内存大小。
    printf("RssShmem:\t%8lu kB\n", shmem);//----------------------------------共享内存RSS内存大小。
    printf("VmData:\t%8lu kB\n", mm->data_vm);//------------------------------------程序数据段的所占虚拟内存大小,存放了初始化了的数据。
    printf("VmStk:\t%8lu kB\n", mm->stack_vm);//-------------------------------------进程在用户态的栈大小。
    printf("VmExe:\t%8lu kB\n", text);//-------------------------------------进程主程序代码段内存使用量,即text段大小。
    printf("VmLib:\t%8lu kB\n", lib);//-------------------------------------进程共享库内存使用量。
    printf("VmPTE:\t%8lu kB\n", ptes);//-------------------------------------进程页表项Page Table Entries内存使用量。
    printf("VmPMD:\t%8lu kB\n", pmds);//-------------------------------------进程PMD内存使用量。
    printf("VmSwap:\t%8lu kB\n", swap);//-----------------------------------进程swap使用量。
}

int main(int argc, char* argv[])
{
    if(argc!=2) {
        cout<<"getProcessMemorySize <size>MB"<<endl;
        return 0;
    }

    int size = atoi(argv[1]);

    // 获取当前进程的句句句句句柄
    pid_t pid = getpid();

    std::cout<<"pid:"<<pid<<std::endl;

    char *c = (char*)malloc(size*1024*1024);

    struct mm_struct* mm = get_mm_struct_by_pid(pid);
    if (mm==NULL) {
        cout<<"cant get process:"<<pid<<" mm_struct!"<<endl;
        return 0;
    }

    outputMM_Struct(mm);

文章目录